0

こちらは少し長めです。

直接の親だけでなく、すべての祖先を認識する子ディレクティブを作成するにはどうすればよいですか?

私が質問している理由は、ラファエル ペーパーへの参照をそのすべての子に提供するラファエル ペーパー ディレクティブが必要だからです。また、さまざまな形状をグループ化できる「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

(質問にはかなりの数の質問があります。問題/質問を示す最小限のフィドルまたはプランカーを使用して、それぞれに個別の質問を投稿すると、より良い、おそらくより速い回答が得られます。)

直接の親だけでなく、すべての祖先を認識する子ディレクティブを作成するにはどうすればよいですか?

ディレクティブが分離スコープを作成しない場合 (提供されたサンプル コードでは、どのディレクティブもこれを行っていません)、ディレクティブは通常の JavaScript プロトタイプ継承を介してすべての祖先の $scopes にアクセスできます。

したがって、ディレクティブでデータを定義する$scopeと、子ディレクティブはそのデータに直接アクセスできます。

たとえば、親ディレクティブのコントローラー関数に次のコードがある場合:

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

次に、子ディレクティブが (コントローラーまたはリンク関数で) アクセスできます。

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

Raphael paper への参照をそのすべての子に提供する Raphael paper ディレクティブが必要です。

したがって、ディレクティブでは、そのディレクティブ( ではなく)rlPaperで "Raphael paper" オブジェクトを定義します。リンク関数の実行が遅すぎるため、リンク関数ではなく、ディレクティブのコントローラー関数でこれを行います。( 2 つのネストされたディレクティブを使用して、ディレクティブのコントローラーとリンク関数がいつ実行されるかを示すFiddle 。)$scopethis

rlShape ディレクティブのリンク関数は、どのようにして独自のコントローラーにアクセスできますか?

これを行う方法はありますが、より良い方法は$scope、ディレクティブのリンクおよびコントローラー関数によって共有されるディレクティブの にデータと関数を配置することだと思います。

ディレクティブでは、代わりにデータをオブジェクトrlCircleに配置する場合、他の親コントローラーを要求する必要はありません。$scope

于 2013-04-03T04:04:56.433 に答える