我们有以下情况:
有一个可以有x个输入元素的容器(x> = 0) 每个输入元素都使用正常的ng-binds
在容器中有一个函数,它为每个包含的ngModelController添加$ parsers和$ validators。
代码如下:
<form-element>
<fs-input-a ng-required="true" ng-model="model.streetname" name="streetname"></fs-input-a>
<fs-input-b ng-required="true" ng-maxlength="5" ng-pattern="/\d$/" ng-model="model.streetnr" name="streetnr"></fs-input-b>
</form-element>
在&#34; form-element&#34;的链接方法中指令我们称之为: var controls = element [0] .querySelectorAll(&#39; [ng-model]&#39;), 我,ngModel;
// Get all ngModel controllers
if (controls.length) {
for (i = 0; i < controls.length; i++) {
ngModel = angular.element(controls[i]).controller('ngModel');
ngModel.$parsers.push(function(value) {
...
}.bind(ngModel));
ngModel.$validators.removeHidden = function() {
// on validation remove the hideError flag
this.$hideError = undefined;
return true;
}.bind(ngModel);
}
}
这在AngularJS 1.4.x下运行良好
在AngularJS 1.5.x中,只有当输入指令中的模板通过模板直接定义时,它才有效:&#39; ...&#39; 如果我们使用templateUrl:&#39; ...&#39;我们现在有一个问题,即ngModel将是未定义的。 在控件[i]中,我得到了正确的元素,并且有一个ng-model属性,但似乎AngularJS 1.5没有编译元素。
有没有更好的方法来操纵子元素的ngModel?
答案 0 :(得分:0)
编译是懒惰的,因此没有办法以当前的方式可靠地执行此操作,父指令无法知道其子项已编译并准备就绪。在解析父/兄弟控制器时调用$onInit
,并且$postLink
,templateUrl
是(最有可能的?)编译指令时调用的最后一个生命周期方法:
$ postLink() - 在此控制器的元素及其子元素已被链接之后调用。与post-link函数类似,此钩子可用于设置DOM事件处理程序并执行直接DOM操作。请注意,包含
require: { ... parent: '^parentComponent' }, controller: function() { this.$onInit = () => this.parent.initialiseNgModel(...); }
指令的子元素将不会被编译和链接,因为它们正在等待其模板异步加载,并且它们自己的编译和链接已暂停,直到发生这种情况。
这似乎表明你不应该试图通过DOM访问子控制器,无论如何。
是否有任何特殊原因需要同时循环遍历所有控制器?如果您只是对所有控制器进行相同的初始化,那么另一种方法是将容器作为所需的控制器添加到子节点中并在那里进行,例如,在子组件中:
#pgc-x-x-x.panel-grid-cell {
display: inline-block;
float: none !important;
vertical-align: middle; }
或者,如果无法修改子项(或只是为了保持代码分开),请使用ng-init或属性指令。
如果父控制器必须立即执行所有这些操作,则绝对必要。然后一个不太好的解决方案是为子组件添加一种方式来表示他们已编译并且父级计算有多少并且等待所有这些组件在继续使用代码之前完成。