Jac*_*opo 22 javascript angularjs
我有一个包含an的AngularJS指令,ngIf我想修改ngIf指令链接函数中的一些DOM .不幸的是,似乎ngIf阻止我在链接函数中查找其中的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
}
};
});
Run Code Online (Sandbox Code Playgroud)
这是指令的简化html:
<div class="column">
<div>{{ column.title }}</div>
<form name="columnForm" role="form" ng-if="editing">
<select></select>
</form>
</div>
Run Code Online (Sandbox Code Playgroud)
这是jsFiddle示例http://jsfiddle.net/dedalusj/Y49Xx/1/的链接
element.findlink函数中的调用返回一个空数组,但是一旦ngIf从表单中删除它,它就会返回正确的select DOM元素.我觉得我这样做的方式不对.
UPDATE
谢谢你的答案,但我找到了另一种解决方案.我只是创建了另一个封装表单的column指令,并将其添加到指令模板中ng-if="editing".
form指令没有自己的作用域,所以它有效地在column指令作用域内运行,并且总是访问该select元素,因为它在DOM树中.我支付额外指令的费用,但我不必使用$timeout黑客.我创建了一个新的jsFiddle来说明解决方案http://jsfiddle.net/dedalusj/nx3vX/1/
谢谢@Michael,但我不能简单地使用它,ng-option因为types数组来自XML文件,其元素是其他angular.element对象,无法轻松插入ng-option.
Rob*_*ght 11
该ngIf指令使用Angular的转换功能.在编译/链接循环期间发生的事情是:
ngIf编译时,内容中的内容将从DOM中删除ngIf的链接功能正在使用它的指令链接功能之前运行.当ngIf链接函数运行时,它用于$scope.$watch()监视ng-if
属性的值.ngIf不是DOM的一部分ngIf然后如果属性值是真实的,则调用该$transclude函数以将该内容插入ngIf到DOM中ng-if.$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
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
正如 @modern Degree 所说,ngIf从 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>');
});
};
}
Run Code Online (Sandbox Code Playgroud)
在这里更新了 jsFiddle 。
这里的技巧是find()使用$timeout0 间隔来延迟调用,以等待 Angular 更新 DOM。
更新
在对您的代码进行了更多思考之后,我意识到也许您可以让 Angular 为您完成艰苦的工作:
JavaScript
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;
};
}],
};
});
Run Code Online (Sandbox Code Playgroud)
超文本标记语言
<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>
Run Code Online (Sandbox Code Playgroud)
现在您无需担心select在正确的时间找到元素并填充它。Angular 会为你完成这一切。:)
| 归档时间: |
|
| 查看次数: |
10124 次 |
| 最近记录: |