我面临一个非常奇怪的问题,一个控制器中的变量被另一个控制器劫持。以下是详细信息:
在我的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只是为了进一步检查
大师,我是新手,非常感谢你的帮助。
答案 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