Функция ссылки пользовательской директивы вызывается перед повторным использованием ng-repeat

У меня есть следующая директива:

.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);

но это чувствует себя "счастливым"

Есть ли что-то, чего мне не хватает для достижения моей цели более простым способом? в общем, как лучше всего манипулировать элементом dg-repeat dom внутри функции link пользовательской директивы?

Спасибо, Джимми.

2 ответа

Решение

Ты можешь проверить $scope.$evalAsync

$scope.$evalAsync(function(){
    $(element.find("img")[0]).css({display: "block"});
}

Это сделает функцию выполненной после рендеринга dom.

Кроме того, использование $timeout не является плохой идеей, если вы установите задержку на 0

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

Я также изменил способ выбора элементов в вашей директиве. Так как у вас есть element В наличии вы можете просто использовать JQLite. Однако, чтобы просто изменить класс CSS, вы должны сделать это в файле 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>