2016-04-15 108 views
0

我面臨一個非常奇怪的問題,一個控制器中的變量被另一個控制器劫持。這裏是細節:angularjs:控制器劫持另一個控制器的變量

在我的HTML我有兩個ng-view標籤。每個標籤都會導致一個templateURL(一個html),它有自己相應的控制器。 CTRL1和CTRL2

兩個NG-觀點是在HTML層級中同一水平 - 也就是說,一個是不是另一個

控制器1的孩子是這樣的:

ngEpMod.controller('Ctrl1',[function() { 

    selfX = this; 

    abc = 'abc controller1'; 
    console.log(abc); // break point 1 

    selfX.query = function() { 
     console.log("abc="); 
     console.log(abc); // break point 2 
     console.log("search query="); 
     console.log(selfX.searchQ); 
     lySP.searchHomes(); 

    }; 

}]); 

控制器2外觀像這樣:

ngEpMod.controller('Ctrl2',[function() { 

    self = this; 
    abc = 'abc controller2'; 

}]); 

兩個控制器都使用「控制器as」語法在html中關聯。

在CTRL1查詢()方法時,用戶用戶點擊一個按鈕(NG-點擊)

之謎被觸發:當我加載HTML頁面($狀態),有兩個NG-意見,我觀察瀏覽器控制檯。我注意到break-point1的abc值是「abc controller1」,但是當query()方法被觸發時,它神祕地變爲「abc controller2」。這個名字沒有全局變量!據我瞭解,當頁面佈局時,Ctrl1是首先創建的,所以在斷點1處,abc具有正確的值,然後創建Ctrl2,並以某種方式高度地插入abc變量!更奇怪的是,我首先注意到這個問題與我自我變量(自我= this),然後我介紹abc只是爲了進一步檢查

大師,我是一個新手,並會真正感謝您的幫助。

回答

0

通過創建無var(或ES6 let)一個變量,你已經創建連接到窗口的全局變量:

abc = 'abc controller1';等於window.abc = 'abc controller1';

當第一控制器對其進行實例聲明變量abc在窗口上。當第二個控制器實例化時,它會更改全局變量內容abc

爲了避免在這種情況下在兩個控制器中定義var abc

爲了避免在將來添加'use strict';每個功能的減速,例如:

ngEpMod.controller('Ctrl2',[function() { 
    'use strict'; 

    self = this; 
    var abc = 'abc controller2'; 

}]); 

嚴格模式將引發錯誤,當你犯了這個錯誤(任何其他許多人)。來自MDN:

首先,嚴格模式使得不可能無意中創建全局變量 。在正常的JavaScript中,如果忽略了賦值 中的變量,將會在全局對象上創建一個新屬性,並繼續「工作」 (儘管未來可能失敗:可能在現代JavaScript中)。 分配這將意外地而不是扔在嚴格模式 創建全局變量:

+0

謝謝Ori - 我剛剛將var添加到abc並且工作正常!我是一個虛擬 - 編碼缺乏足夠的JavaScript知識的缺點。 – hpep

+0

不用擔心。閱讀['嚴格使用'](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Strict_mode),並使用它。這將有助於發現錯誤,並教你不該做什麼。另外,閱讀[Javascript good part](http://bdcampbell.net/javascript/book/javascript_the_good_parts.pdf)書。 –

0

我將下面的代碼放到你的應用實例化這上面(大部分現代瀏覽器應該能夠理解這個語法用於調試)。在每個控制器構造函數中調用window.trackCtrl,然後在chrome或firefox中打開控制檯並鍵入printCtrls(),並且您應該在按順序創建時打印出來。

window.trackCtrl = (name) => { 
    var newCtrl = {} 
    newCtrl.name = name + '_' + performance.now() 
    window.trackingCtrls = window.trackingCtrls || [] 
    window.trackingCtrls.push(newCtrl) 
} 

window.printCtrls =() => Array.isArray(window.trackCtrls) ? window.trackingCtrls.forEach(x => console.info(x)) : console.error('trackCtrls not defined') 

這將發現的bug,如控制器負載越來越亂序或重複的代碼或庫的副本加載得到在同一頁上。性能API在這些情況下有很大幫助=>https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

+0

會做 - 謝謝cmbernerlain – hpep

相關問題