级联角度指令

时间:2013-11-14 17:07:53

标签: angularjs angularjs-directive

我有以下Angular绑定设置:

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

正如你所看到的,我绑定了一个项目列表,绑定了内部div背景,还有一个自定义指令'app-shadow'。

我的指令的代码是:

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

appShadow指令依赖于现有的js库(jQuery Illuminate),它使用给定元素的父背景颜色。它使用JQuery.css("background-color")来确定父元素的bg颜色(上面源链接的第22行)。

我的问题似乎是,当评估父bgcolour时,它不是Angular绑定的。我猜这两个指令之间存在竞争条件。

我可以做些什么来确保ng-style指令在我的自定义指令之前得到评估?

提前致谢。

2 个答案:

答案 0 :(得分:3)

确实发生了这种情况,因为可能出现竞争条件并将您的代码置于$timeout(..., 0)内可能会通过一个$digest循环强行推迟解决它。

但是,如果app.bgColour在{/ 1}}指令初始化之后更改了,这可能会继续存在问题。

在这种情况下,最好的解决方案通常是在您依赖的属性上设置app-shadow

$watch

模板:

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

答案 1 :(得分:1)

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

Live demo (click).

我会使用该指令来建立一个看起来很自然且更具扩展性的手表。 否则,我会像这样使用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);
        }
      };
    }
  };
});