在替换 ng-repeat 之前调用自定义指令 link 函数
custom directive's link function is invoked before ng-repeat is replcaed
我有以下指令:
.directive("picSwitcher", ["$timeout", function($timeout){
return {
restrict: "A",
scope: {
pics: "=",
fadeTime: "@",
timeForPic:"@"
},
template: '<img ng-repeat="pic in pics" src="{{pic.url}}" style="display: none"/>',
link: function ($scope, element){
//some code...
$(element.find("img")[0]).css({display: "block"});
}
};
}])
我的问题是,当我的 link 函数被调用时 - ng repeat 尚未 "compile"(这里应该使用什么词而不是编译?)
所以我试图将 css 设置为 undefined..
如何在 ng-repeat 完成后将 link 函数强制为 运行?!
目前我正在通过将 $(element.find("img")[0]).css({display: "block"});
替换为 $timeout(function(){
$(element.find("img")[0]).css({display: "block"});}, 200);
来解决这个问题
但那种感觉'hacky'
我是否缺少以更轻松的方式实现目标的方法?
一般来说,在自定义指令的 link 函数中操作 ng-repeat dom 元素的最佳方法是什么?
谢谢,
吉米.
你可以查看$scope.$evalAsync
$scope.$evalAsync(function(){
$(element.find("img")[0]).css({display: "block"});
}
这将使函数在 dom 渲染后执行。
此外,如果您将延迟设置为 0
,使用 $timeout 也是一个不错的主意
$timeout(function(){
$(element.find("img")[0]).css({display: "block"});},
0);
我认为也会达到目的。
更多参考http://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm
您可以使用 JQLite 的 .ready()
函数。
post: function postLink(scope, element) {
element.ready(function() {
//$(element.find("li")[0]).css({color: "red"});
element.find("li:first-child").css({color: "red"});
});
}
我还更改了指令中 select 元素的方式。由于您有 element
可用,您可以只使用 JQLite。但是,要仅更改 css class,您应该在 CSS 文件中进行。
在下面的代码片段中,我将 <img>
替换为 <ul><li>
,但它对图像的效果相同。
function myDirective() {
return {
template : '<ul><li ng-repeat="pic in pics">{{pic.name}}</li></ul>',
scope: {
pics: '='
},
link: function(scope, element) {
element.ready(function() {
//$(element.find("li")[0]).css({color: "red"});
element.find("li:first-child").css({color: "red"});
});
}
}
}
function SuperController() {
this.pics = [{name:"rob"}, {name:"jules"}, {name:"blair"}];
}
angular.module('myApp', []);
angular
.module('myApp')
.controller('SuperController', SuperController)
.directive('myDirective', myDirective);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="SuperController as s">
<my-directive pics="s.pics">
</my-directive>
</div>
</div>
我有以下指令:
.directive("picSwitcher", ["$timeout", function($timeout){
return {
restrict: "A",
scope: {
pics: "=",
fadeTime: "@",
timeForPic:"@"
},
template: '<img ng-repeat="pic in pics" src="{{pic.url}}" style="display: none"/>',
link: function ($scope, element){
//some code...
$(element.find("img")[0]).css({display: "block"});
}
};
}])
我的问题是,当我的 link 函数被调用时 - ng repeat 尚未 "compile"(这里应该使用什么词而不是编译?)
所以我试图将 css 设置为 undefined.. 如何在 ng-repeat 完成后将 link 函数强制为 运行?!
目前我正在通过将 $(element.find("img")[0]).css({display: "block"});
替换为 $timeout(function(){
$(element.find("img")[0]).css({display: "block"});}, 200);
但那种感觉'hacky'
我是否缺少以更轻松的方式实现目标的方法? 一般来说,在自定义指令的 link 函数中操作 ng-repeat dom 元素的最佳方法是什么?
谢谢, 吉米.
你可以查看$scope.$evalAsync
$scope.$evalAsync(function(){
$(element.find("img")[0]).css({display: "block"});
}
这将使函数在 dom 渲染后执行。
此外,如果您将延迟设置为 0
,使用 $timeout 也是一个不错的主意$timeout(function(){
$(element.find("img")[0]).css({display: "block"});},
0);
我认为也会达到目的。
更多参考http://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm
您可以使用 JQLite 的 .ready()
函数。
post: function postLink(scope, element) {
element.ready(function() {
//$(element.find("li")[0]).css({color: "red"});
element.find("li:first-child").css({color: "red"});
});
}
我还更改了指令中 select 元素的方式。由于您有 element
可用,您可以只使用 JQLite。但是,要仅更改 css class,您应该在 CSS 文件中进行。
在下面的代码片段中,我将 <img>
替换为 <ul><li>
,但它对图像的效果相同。
function myDirective() {
return {
template : '<ul><li ng-repeat="pic in pics">{{pic.name}}</li></ul>',
scope: {
pics: '='
},
link: function(scope, element) {
element.ready(function() {
//$(element.find("li")[0]).css({color: "red"});
element.find("li:first-child").css({color: "red"});
});
}
}
}
function SuperController() {
this.pics = [{name:"rob"}, {name:"jules"}, {name:"blair"}];
}
angular.module('myApp', []);
angular
.module('myApp')
.controller('SuperController', SuperController)
.directive('myDirective', myDirective);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="SuperController as s">
<my-directive pics="s.pics">
</my-directive>
</div>
</div>