在替换 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>