[英]Collection does not work if used inside ng-if, but work with ng-show
I just upgraded Angular from 1.4.8 to 1.6.4 in my application and I am facing an issue with a select menu that gets the data from a controller variable. 我刚刚在我的应用程序中将Angular从1.4.8升级到1.6.4,我遇到了一个选择菜单的问题,该菜单从控制器变量中获取数据。
html: HTML:
<div id='main_app_header' ng-if="ctrl.shouldShowHeader">
<accounts-directive></accounts-directive>
</div>
The accounts directive has the select menu. accounts指令具有选择菜单。
<div class="account-selector" ng-class="{'account-selector-disabled': haCtrl.accounts.length == 1}">
<select id="account-select" ng-model="haCtrl.current"
ng-options="account as account.name for account in haCtrl.accounts track by account.id"
ng-change="haCtrl.changeAccount()"
ng-disabled="haCtrl.accounts.length == 1">
</select>
</div>
When inspecting controllers all data is there. 检查控制器时,所有数据都在那里。 If i change the ng-if
to ng-show
everything works fine. 如果我改变ng-if
到ng-show
一切正常。 I do not want to use `ng-show as not wanted to increase the number of watchers in the DOM. 我不想使用`ng-show,因为不想增加DOM中观察者的数量。 Is there something wrong I am doing? 我在做什么不对劲?
Directive Code: 指令代码:
"use strict";
(function() {
var AccountsDirective = function() {
return {
restrict: 'E',
replace: true,
templateUrl: "app/components/header/account/view.html",
controller: 'HeaderAccountCtrl as haCtrl'
};
};
angular.module('mainNgApp').directive('AccountsDirective', AccountsDirective);
})();
Controller Code: 控制器代码:
"use strict";
(function() {
var HeaderAccountCtrl = function(
$scope,
atomico,
events,
userState
) {
var _this = this;
atomico.ready(function() {
_this.accounts = atomico.metadata['accounts'];
_this.current = atomico.metadata['account'];
});
_this.changeAccount = function(){
atomico.metadata['account'] = _this.current;
userState.setActiveAccountId(_this.current.id, function() {
events.account.change(_this.current);
});
};
};
HeaderAccountCtrl.$inject = [
'$scope',
'atomico',
'events',
'userState'
];
angular.module('mainNgApp').controller('HeaderAccountCtrl', HeaderAccountCtrl);
})();
The errors i get when switching to ng-if
are as below: 切换到ng-if
时出现的错误如下:
TypeError: Cannot read property 'appendChild' of undefined
at updateOptions (angular-1.6.4.self-cbf63df….js?body=1:30346)
at Object.ngOptionsPostLink (angular-1.6.4.self-cbf63df….js?body=1:30249)
at angular-1.6.4.self-cbf63df….js?body=1:1347
at invokeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:10427)
at nodeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:9816)
at compositeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:9056)
at nodeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:9810)
at delayedNodeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:10177)
at compositeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:9056)
at compositeLinkFn (angular-1.6.4.self-cbf63df….js?body=1:9059) ""
TypeError: Cannot read property 'value' of undefined
at SelectController.writeNgOptionsValue [as writeValue] (angular-1.6.4.self-cbf63df….js?body=1:30117)
at Object.ngModelCtrl.$render (angular-1.6.4.self-cbf63df….js?body=1:32811)
at ngModelWatch (angular-1.6.4.self-cbf63df….js?body=1:28960)
at Scope.$digest (angular-1.6.4.self-cbf63df….js?body=1:17992)
at Scope.$apply (angular-1.6.4.self-cbf63df….js?body=1:18270)
at HTMLAnchorElement.<anonymous> (angular-1.6.4.self-cbf63df….js?body=1:27000)
at HTMLAnchorElement.dispatch (jquery.self-bd7ddd3….js?body=1:5227)
at HTMLAnchorElement.elemData.handle (jquery.self-bd7ddd3….js?body=1:4879)
TypeError: Cannot read property 'value' of undefined
at SelectController.writeNgOptionsValue [as writeValue] (angular-1.6.4.self-cbf63df….js?body=1:30117)
at Object.ngModelCtrl.$render (angular-1.6.4.self-cbf63df….js?body=1:32811)
at angular-1.6.4.self-cbf63df….js?body=1:30156
at Scope.$digest (angular-1.6.4.self-cbf63df….js?body=1:18000)
at Scope.$apply (angular-1.6.4.self-cbf63df….js?body=1:18270)
at HTMLAnchorElement.<anonymous> (angular-1.6.4.self-cbf63df….js?body=1:27000)
at HTMLAnchorElement.dispatch (jquery.self-bd7ddd3….js?body=1:5227)
at HTMLAnchorElement.elemData.handle (jquery.self-bd7ddd3….js?body=1:4879)
TypeError: Cannot read property 'nodeName' of undefined
at nodeName_ (angular-1.6.4.self-cbf63df….js?body=1:886)
at getBooleanAttrName (angular-1.6.4.self-cbf63df….js?body=1:3497)
at Attributes.$set (angular-1.6.4.self-cbf63df….js?body=1:8650)
at ngBooleanAttrWatchAction (angular-1.6.4.self-cbf63df….js?body=1:22801)
at Scope.$digest (angular-1.6.4.self-cbf63df….js?body=1:18000)
at Scope.$apply (angular-1.6.4.self-cbf63df….js?body=1:18270)
at HTMLAnchorElement.<anonymous> (angular-1.6.4.self-cbf63df….js?body=1:27000)
at HTMLAnchorElement.dispatch (jquery.self-bd7ddd3….js?body=1:5227)
at HTMLAnchorElement.elemData.handle (jquery.self-bd7ddd3….js?body=1:4879)
The error is suggesting that accounts
is not defined. 该错误表明未定义accounts
。 Looking at your controller code, this is set via the atomico.ready()
function which is where the problem is going to be. 查看控制器代码,这是通过atomico.ready()
函数设置的,这是问题所在。
ngShow
only hides elements in the DOM whereas ngIf
will add and remove them. ngShow
只隐藏DOM中的元素,而ngIf
将添加和删除它们。
What is happening is that the ngIf
is adding your component into the DOM, and it is only at this point that the controller is instantiated. 发生的事情是ngIf
正在将您的组件添加到DOM中,并且仅在此时控制器被实例化。 However the atomico.ready()
is not being called because (I assume) it has already been called when the page was loaded. 然而, atomico.ready()
没有被调用,因为(我假设)它已经在页面加载时被调用。
I'm not sure what the atomico
service/factory is, but I'd suggest passing arguments to the directive instead of using it in the directive. 我不确定atomico
服务/工厂是什么,但我建议将参数传递给指令而不是在指令中使用它。 That way the page can handle the atomico.ready()
callback instead, and pass the results to the directive when needed. 这样页面就可以处理atomico.ready()
回调,并在需要时将结果传递给指令。
So, make use of the bindToController
parameter: 因此,请使用bindToController
参数:
var AccountsDirective = function() {
return {
restrict: 'E',
replace: true,
templateUrl: "app/components/header/account/view.html",
controller: 'HeaderAccountCtrl as haCtrl',
scope: {},
bindToController: {
accounts: "<"
}
};
};
And pass in using: 并传递使用:
<accounts-directive accounts="ctrl.accounts"></accounts-directive>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.