2

I have the following Angular binding setup:

<div ng-repeat="app in vm.Apps">
    <div ng-style="{ background: app.bgColour }">           
        <p app-shadow="large"></p>
    </div>      
</div>

As you can see, I'm binding to a list of items, binding the inner div background, and also have a custom directive 'app-shadow'.

The code for my directive is:

function addShadowDirective($document) {
    return function (scope, element, attr) {
        $(element).iluminate(
            { size: 64, textSize: 30, alpha: 0.5, textAlpha: 0.2, fade: 0, fadeText: 0, includeText: false, textOnly: true, direction: "bottomRight" });
    };
}

The appShadow directive depends on an existing js library (jQuery Illuminate) which uses the parent background colour of the given element. It uses JQuery.css("background-color") to determine the parent element's bg colour (line 22 of the source link above).

My problem seems to be that when parent bgcolour is evaluated, it's not what Angular has bound. I'm guessing there's a race condition between the two directives.

Any ideas for what I can do to ensure the ng-style directive is evaluated before my custom directive?

Thanks in advance.

4

2 回答 2

3

这确实发生了,因为可能是因为竞争条件,并且将您的代码放在 a 中$timeout(..., 0)可能会通过强制将其延迟一个$digest循环来解决它。

但是,如果在您的指令初始化之后app.bgColour发生更改,这可能仍然是一个问题。app-shadow

在这种情况下,最好的解决方案通常是$watch在您依赖的属性上设置 a:

link: function (scope, elem, attrs) {
      // ...
      scope.$watch(attrs.color, function (newVal) { 
          if (typeof newVal !== 'undefined') {
              var color = newVal;
              // ... 
          }
      });
 }

模板:

<p app-shadow="large" color="app.bgColor"></p>
于 2013-11-14T17:29:47.357 回答
1

我做了一个演示,您可以在其中查看控制台日志以查看 compile、postLink 和 preLink 在父子节点之间运行的顺序。在此示例中,您可以看到两者都可以访问scope,但父逻辑在子逻辑之前运行,这似乎是您的目标。

现场演示(点击)。

我会使用该指令来建立一个手表,它看起来很自然并且更具可扩展性。否则,我会像这样使用 post/pre 执行顺序:

<div parent>Should be red.          
  <p child>Should be green.</p>
</div>


var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope) {
  $scope.bkgr = 'red';
  $scope.bkgr2 = 'green';
});

app.directive('parent', function() {
  return {
    compile: function(element, attrs) {
      console.log('parent compile');
      return {
        pre: function(scope, element, attrs) {
          console.log('parent pre');
          element.css('background-color', scope.bkgr);
        },
        post: function(scope, element, attrs) {
          console.log('parent post');
        }
      };
    }
  };
});

app.directive('child', function() {
  return {
    compile: function compile(element, attrs) {
      console.log('child compile');
      return {
        pre: function preLink(scope, element, attrs) {
          console.log('child pre');
        },
        post: function postLink(scope, element, attrs) {
          element.css('background-color', scope.bkgr2);
        }
      };
    }
  };
});
于 2013-11-14T18:24:34.097 回答