2016-04-15 109 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

相关问题