0

这是一个略长的。

我怎样才能让子指令知道他们所有的祖先,而不仅仅是他们的直接父母?

我问的原因是我想要一个 Raphael 论文指令,为所有子项提供对 Raphael 论文的引用。另外,我试图有一个“rl-shape”指令,可以将不同的形状组合在一起,这样它们就可以一起翻译、转换等。我还希望这个“rl-shape”指令能够出现在自身内部,允许任意形状的树。

可能有一种完全不同的更好的方法来做到这一点。如果是这样,请纠正我。

这是我到目前为止的代码:

<!doctype html>
<html xmlns:ng="http://angularjs.org" ng-app="myApp">
  <head>
    <title>Test</title>

    <script src="js/underscore.js"></script>
    <script src="js/raphael-min.js"></script>
  </head>

  <body>
    <rl-paper>
      <rl-shape name="myShape">
        <rl-circle name="inner" cx="0" cy="0" r="50"></rl-circle>
        <rl-circle name="outer" cx="0" cy="0" r="100"></rl-circle>
      </rl-shape>
    </rl-paper>

    <p>
      <button ng-click="myShape.translate(0, -10)">Move shape up</button>
      <button ng-click="myShape.translate(0, 10)">Move shape down</button>
    </p>

    <script src="js/angular.min.js"></script>
    <script>
      var myApp = angular.module("myApp", []);

      function Shape(children) {
        this.translate = function(dx, dy) {
          _.each(children, function(c) { c.translate(dx, dy); });
        };
      }

      myApp.directive("rlPaper", function() {
        return {
          restrict: "E",
          controller: function($element) {
            this.paper = new Raphael($element[0], 220, 220);
            this.paper.setViewBox(-110, -110, 220, 220);
          }
        };
      });

      myApp.directive("rlShape", function () {
        return {
          restrict: "E",
          require: ["^rlPaper"],
          controller: function($scope, $element, $attrs, $transclude) {
            this.children = [];
          },
          link: function(scope, element, attrs, ctrls) {
            // How can the link function of the rlShape directive access its
            // own controller?  If I could figure that out, I could do
            // something like the following:
            var shapeCtrl = undefined;  // Don't know how to get this

            var shape = Shape(shapeCtrl.children);
            scope[attrs.name] = shape;
          }
        };
      });

      myApp.directive("rlCircle", function() {
        return {
          restrict: "E",
          require: ["^rlPaper", "?^rlShape"],
          link: function(scope, element, attrs, ctrls) {
            var paperCtrl = ctrls[0];
            var shapeCtrl = ctrls[1];

            var circle = paperCtrl.paper.circle(attrs.cx, attrs.cy, attrs.r);
            scope[attrs.name] = circle;

            if ( shapeCtrl ) {
              shapeCtrl.children.push(circle);
            }
          }
        };
      });
    </script>
  </body>
</html>
4

1 回答 1

3

(您的问题中有很多问题。如果您为每个问题发布单独的问题,并使用简约的小提琴或 plunker 展示问题/问题,您会得到更好的,并且可能更快的答案。)

我怎样才能让子指令知道他们所有的祖先,而不仅仅是他们的直接父母?

如果指令没有创建隔离范围(在您提供的示例代码中,您的指令都没有这样做),那么该指令可以通过正常的 JavaScript 原型继承访问所有祖先的 $scopes 。

因此,如果您在指令中定义数据$scope,子指令将能够直接访问该数据:

例如,如果您在父指令的控制器函数中有此代码:

$scope.paper = new Raphael($element[0], 220, 220);

然后子指令可以访问它(在它们的控制器或链接函数中):

var paper = $scope.paper;  // prototypal inheritance will find it

我想要一个 Raphael 论文指令,为所有子项提供对 Raphael 论文的引用。

因此,在rlPaper指令中,在该指令$scope(而不是this)上定义一个“Raphael paper”对象。在指令的控制器函数中执行此操作,而不是链接函数,因为链接函数将运行得太晚。(小提琴显示指令的控制器和链接函数何时运行,带有两个嵌套指令。)

rlShape 指令的链接功能如何访问自己的控制器?

有一种方法可以做到这一点,但我认为更好的方法是将数据和函数放在指令的$scope,由指令的链接和控制器函数共享。

在指令中,如果您将数据放到对象rlCircle上,则不必要求其他父控制器。$scope

于 2013-04-03T04:04:56.433 回答