Javascript AngularJS ngIf阻止在指令内查找元素
我有一个包含Javascript AngularJS ngIf阻止在指令内查找元素,javascript,angularjs,Javascript,Angularjs,我有一个包含ngIf的AngularJS指令,我想在指令链接函数中修改ngIf中的一些DOM。不幸的是,ngIf似乎阻止我在link函数中查找其中的DOM元素 以下是该指令的代码: directive('column', function () { return { templateUrl: 'views/column.html', restrict: 'E', scope: { column: '=' }, c
ngIf
的AngularJS指令,我想在指令链接函数中修改ngIf
中的一些DOM。不幸的是,ngIf
似乎阻止我在link函数中查找其中的DOM元素
以下是该指令的代码:
directive('column', function () {
return {
templateUrl: 'views/column.html',
restrict: 'E',
scope: {
column: '='
},
controller: ['$scope', function ($scope) {
$scope.editing = true;
$scope.toggleEditing = function () {
$scope.editing = !$scope.editing;
};
}],
link: function postLink(scope, element) {
var select = element.find('select');
console.log(select); // See if it can find the select element
// var types = scope.column.types();
// add types as options to the select element
}
};
});
<div class="column">
<div>{{ column.title }}</div>
<form name="columnForm" role="form" ng-if="editing">
<select></select>
</form>
</div>
以下是该指令的简化html:
directive('column', function () {
return {
templateUrl: 'views/column.html',
restrict: 'E',
scope: {
column: '='
},
controller: ['$scope', function ($scope) {
$scope.editing = true;
$scope.toggleEditing = function () {
$scope.editing = !$scope.editing;
};
}],
link: function postLink(scope, element) {
var select = element.find('select');
console.log(select); // See if it can find the select element
// var types = scope.column.types();
// add types as options to the select element
}
};
});
<div class="column">
<div>{{ column.title }}</div>
<form name="columnForm" role="form" ng-if="editing">
<select></select>
</form>
</div>
{{column.title}}
下面是指向JSFIDLE示例的链接
link函数中的元素.find
调用返回一个空数组,但只要我从表单中删除ngIf
,它就会返回正确的select DOM元素。我觉得我这样做是不对的
更新
谢谢你的回答,但我找到了另一个解决办法。我只是创建了另一个封装表单的指令,并使用ng if=“editing”
将其添加到列
指令模板中
表单指令没有自己的作用域,因此它有效地在列
指令作用域之外运行,并且始终可以访问select
元素,因为它位于其DOM树中。我支付额外指令的费用,但我不必使用$timeout
hack。我创建了一个新的JSFIDLE来说明解决方案
谢谢@Michael,但我不能简单地使用
ng选项
,因为类型
数组来自一个XML文件,它的元素是其他angular.element对象,使用ng选项
很难插入 正如@modendegree所说,ngIf
从DOM中删除应用它的元素,因此当它不在DOM中时,您将无法找到它。但是,您可以通过编写指令的方式来解决以下问题:
controller: function ($scope, $element, $timeout) {
$scope.toggleEditing = function () {
$scope.editing = !$scope.editing;
$timeout(function() {
var select = $element.find('select');
select.append('<option>Value 1</option>')
.append('<option>Value 2</option>')
.append('<option>Value 3</option>');
});
};
}
HTML
<div class="column">
<div>{{ column.title }}</div>
<form name="columnForm" role="form" ng-if="editing">
<select ng-model="type" ng-options="type for type in column.types"></select>
</form>
</div>
{{column.title}}
现在,您不必担心在正确的时间找到
select
元素并填充它。Angular为您完成了所有这一切。:) 您可以将链接函数中的代码放入$timeout中
$timeout(function(){
var select = element.find('select');
console.log(select);
});
不要忘记在指令中注入$timeout
directive('column', function ($timeout) {
ngIf
指令通过使用Angular的转换功能工作。编译/链接周期中发生的情况是:
ngIf
中的内容将从DOM中删除ngIf
的链接功能在
使用它的指令的链接函数。当ngIf
的链接功能
运行时,它使用$scope.$watch()
来监视ng的值(如果
属性ngIf
的内容不是DOM的一部分ng if
属性值为truthy,则ngIf
将调用$transclude
函数将ngIf
的内容插入DOM$timeout
调用或使用$scope.$evalAsync
都将运行ngIf
内容中的元素,则需要在上述步骤4之后运行代码。这意味着在指令的链接函数中使用$scope.$watch
、$timeout
或$scope.$evalAsync
注册的任何函数都可以工作。对于一次性的设置代码,我可能会选择$scope.$evalAsync
:
angular.directive('yourDirective', function () {
return {
...
link: function(scope, elem) {
scope.$evalAsync(function () {
// code that runs after conditional content
// with ng-if has been added to DOM, if the ng-if
// is enabled
});
}
};
});
我曾经遇到过同样的问题,我能够使用ng show解决这个问题,这可以防止出现这个问题,因为ngIf删除了它应用于DOM的元素,所以当它不存在时,您将无法找到它 因此,在你的情况下:
<div class="column">
<div>{{ column.title }}</div>
<form name="columnForm" role="form" ng-show="editing">
<select></select>
</form>
{{column.title}}
行
干杯。ngIf阻止将元素添加到DOM中。使用ngShow您可能会更幸运。是的,这是事实,但表单可以包含多个其他指令,并且它所属的指令在文档中多次出现,因此最好不要将其全部包含在DOM中。我希望有一种方法可以做到这一点。下面是一个Plunker,它通过基于Angular 1.4.x中的源代码的自定义版本的
ngIf
演示了这一点:使用ng时,show
元素将加载到DOM中,在大多数情况下它是不需要的