angularjs:控制器劫持另一个控制器的变量

时间:2016-04-15 21:14:24

标签: angularjs angularjs-scope

我面临一个非常奇怪的问题,一个控制器中的变量被另一个控制器劫持。以下是详细信息:

在我的HTML中,我有两个ng-view标签。每个标记都会导致templateURL(一个html)具有自己的相应控制器。 Ctrl1和Ctrl2

两个ng-views在html层次结构中处于同一级别 - 也就是说,一个不是另一个的子级

Controller1如下所示:

    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();

    };

}]);

Controller2看起来像这样:

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

    self = this; 
    abc = 'abc controller2';

}]);

两个控制器都使用“控制器为”语法在html中关联。

当用户用户单击按钮(ng-click)时会触发Ctrl1中的query()方法

神秘:当我加载具有两个ng-views的html页面($ state)时,我正在观察浏览器控制台。我注意到break-point1的abc值是“abc controller1”,但是当query()方法被触发时,它会神秘地改为“abc controller2”。这个名字没有全局变量!据我所知,当页面布局时,首先创建Ctrl1,因此在断点1 abc具有正确的值,然后创建Ctrl2并以某种方式高举插入abc变量!陌生人甚至是我首先用我的自变量(self = this)注意到这个问题然后我引入了abc只是为了进一步检查

大师,我是新手,非常感谢你的帮助。

2 个答案:

答案 0 :(得分: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中)。   意外创建全局变量的赋值   扔严格模式:

答案 1 :(得分: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')

这会发现错误,例如控制器无序加载或代码或库的重复副本加载到同一页面上。在这些情况下,Performance API有很多帮助=> https://developer.mozilla.org/en-US/docs/Web/API/Performance/now