【问题标题】:custom directive's link function is invoked before ng-repeat is replcaed在替换 ng-repeat 之前调用自定义指令链接函数
【发布时间】:2016-11-14 05:29:51
【问题描述】:

我有以下指令:

.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"});
            }
};
}])

我的问题是,当我的链接函数被调用时 - ng repeat 还没有“编译”(这里应该使用什么词而不是编译?)

所以我试图设置未定义的 css.. ng-repeat 完成后如何强制链接功能运行?!

现在我正在通过将$(element.find("img")[0]).css({display: "block"}); 替换为$timeout(function(){ $(element.find("img")[0]).css({display: "block"});}, 200); 来解决这个问题

但这感觉'hacky'

为了以更简单的方式实现我的目标,我还缺少什么吗? 一般来说,在自定义指令的链接函数中操作 ng-repeat dom 元素的最佳方法是什么?

谢谢, 吉米。

【问题讨论】:

  • 也许你会在 html 中做模板而不是在directice 中它会起作用?

标签: javascript angularjs angularjs-ng-repeat angular-directive angular-directive-link


【解决方案1】:

您可以使用 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"});
      });
    }

我还更改了您在指令中选择元素的方式。既然你有 element 可用,你可以只使用 JQLite。但是,要更改一个 CSS 类,您应该在 CSS 文件中进行。

在下面的 sn-p 中,我将 &lt;img&gt; 替换为 &lt;ul&gt;&lt;li&gt;,但它对图像的作用相同。

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>

【讨论】:

  • 好像是这样。不知道为什么!!谢谢你的回答:)
  • 我认为这是一个比公认的答案更好的答案
【解决方案2】:

您可以查看$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

【讨论】:

  • 谢谢,根据您的参考,在我的情况下最好使用 $evalAsync 方法:) 但我很高兴看到我没有做错事。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2015-04-03
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
相关资源
最近更新 更多