7

別のディレクティブ内でディレクティブをレンダリングしようとしています (テンプレート内のリピーターがこれを機能しているかどうかはわかりません)、ディレクティブをコンパイルするのではなく、テキストとして出力するようです (plunkr コードはこちら: http://plnkr.co/編集/IRsNK9 )

リピーター内の my-dir-one、my-dir-two、my-dir-three ディレクティブを実際に適切にレンダリングする方法についてのアイデアはありますか?

index.html

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js"></script>
  <script src="app.js"></script>
  <script id="partials/addressform.html" type="text/ng-template">
      partial of type {{type}}<br>
  </script>
</head>
<body>
  <div container></div>

  <br /><br /><br />
  <b>Below is just to test the directives are actually usable outside the repeater</b>
  <div my-dir-one></div>
  <div my-dir-two></div>
  <div my-dir-three></div>
</body>
</html>

app.js

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

app.directive('container', function () {

  return {
        restrict: 'A',
        scope: {},
        replace: true,

        template: '<div class="views">' +
                  '    <div class="view" ng-repeat="view in views">' +
                  '        <div {{view.dir}}>{{view.dir}}</div>' +
                  '    </div>' +
                  '</div>',

        link: function (scope, elm) {

            scope.views = [
        { dir: 'my-dir-one' },
        { dir: 'my-dir-two' },
        { dir: 'my-dir-three' }
      ];
        }
    }
});

app.directive('myDirOne', function () {
  return {
    restrict: 'A',
    scope: {},
    replace: true,
    template: '<div>This is directive one.</div>'
  }
});

app.directive('myDirTwo', function () {
  return {
    restrict: 'A',
    scope: {},
    replace: true,
    template: '<div>This is directive two.</div>'
  }
});

app.directive('myDirThree', function () {
  return {
    restrict: 'A',
    scope: {},
    replace: true,
    template: '<div>This is directive three.</div>'
  }
});
4

2 に答える 2

8

コードを書き直すことで、この問題を回避することができました。

まず、テンプレート コードを次のように更新しました。

template: '<div class="views">' +
          '    <div class="view-wrapper" ng-repeat="view in views">' +
          '        <div view="{{view.dir}}"></div>' +
          '    </div>' +
          '</div>',

新しい 'view' ディレクティブを作成したことに注意してください。次に、ビュー ディレクティブを次のように定義します。

app.directive('view', ['$compile', function (compile) {

    return {
        restrict: 'A',
        scope: {
            view: '@'
        },
        replace: true,   
        template: '<div class="view"></div>',

        controller: ['$scope', function (scope) {
            scope.$watch('view', function (value) {
                scope.buildView(value);
            });
        }],

        link: function (scope, elm, attrs) {

            scope.buildView = function (viewName) {
                var view = compile('<div ' + viewName + '></div>')(scope);
                elm.append(view);
            }
        }
    }
}]);

基本的に、view.dir 変数は属性として 'view' ディレクティブに渡され、ビューディレクティブはその値を監視して、ディレクティブを含むテンプレートをコンパイルします。

于 2013-05-13T09:47:59.557 に答える
0

これはタイミングの問題の一部です... {{}} 式を解決するまでに、すでに解析され、ディレクティブがレンダリングされていると思います。それ自体が問題なのは、ネスティングやリピーターではありません。

ただし、ここで求めているのは、「変数の値に基づいてレンダリングするディレクティブを決定する」ことです。それにはいくつかの方法があります。

あなたが望むほどうまくスケーリングしないかもしれませんが、これはうまくいくはずです:

<div class='views' ng-repeat='view in views'>
  <div ng-switch='view.dir'>
    <div ng-when='my-dir-one' my-dir-one />
    <div ng-when='my-dir-two' my-dir-two />
    <div ng-when='my-dire-three' my-dir-three />
  </div>
</div>

同様のトリックの他のオプション: ngBindTemplate を使用してデータから文字列を取得し、それを要素のテンプレートとして使用できるようです。これにより、おそらくトリッキーな (そして判読できない) 動作が可能になります。

要素のディレクティブをクラスとして指定できますが、これを行うために ngClass を使用するとディレクティブを動的に選択できるようになるかどうか、またはパイプラインで遅すぎるかどうかはわかりません。

于 2013-05-10T15:15:14.547 に答える