35

auto-carouselリンクされた要素のchildrenを反復処理する1 つのディレクティブがあります。

ng-ifただし、子はs 式がまだ解析されていないため、まだ DOM にロードされていません。

DOM ツリーに変更があったことを親ディレクティブが認識していることを確認するにはどうすればよいですか?

        <ul class="unstyled" auto-carousel>
          <li class="slide" ng-if="name">{{name}}</li>
          ...
          <li class="slide" ng-if="email">{{email}}</li>
        </ul>

使用でき$timeoutましたが、信頼性が低いと感じています。ng-show代わりに使用することもできますng-ifが、それは質問に答えず、必要なものではありません。

4

5 に答える 5

74

だからここに私がやったことがあります:

に関数を渡すことができることを発見しました$scope.$watch。そこから、変更を監視したい式の値を返すのは非常に簡単です。スコープのプロパティにキー文字列を渡すのとまったく同じように機能します。

link: function ($scope, $el, $attrs) {
  $scope.$watch(
    function () { return $el[0].childNodes.length; },
    function (newValue, oldValue) {
      if (newValue !== oldValue) {
        // code goes here
      }
    }
  );
}

リストにはテキストノードとコメントだけでなく要素も含まれているため、childNodesではなくを監視しています。Angular は、要素のみを保持しながらトランスクルージョンを実行して DOM を変更する、、などのディレクティブにコメント プレースホルダーを使用するため、これは貴重です。childrenchildNodesng-repeatng-ifng-switchng-includechildren

于 2014-01-26T08:40:58.197 に答える
18

要素の dom のより深い部分の変更を監視する必要がある場合は、MutationObserver が最適です。

.directive('myDirective', function() {
    return {
        ...
        link: function(scope, element, attrs) {
            var observer = new MutationObserver(function(mutations) {
                // your code here ...
            });
            observer.observe(element[0], {
                childList: true,
                subtree: true
            });
        }
    };
});
于 2015-08-10T19:56:00.380 に答える
5

このangular-dom-eventsのディレクティブ モジュールを作成しました

あなたの場合、あなたはできる

    <ul class="unstyled" auto-carousel>
      <li class="slide" ng-if="name" dom-on-create="nameCreated()">{{name}}</li>
      <li class="slide" ng-if="email" dom-on-destroy="emailDestroyed()">{{email}}</li>
    </ul>

現在は and のみをサポートしdom-on-createdom-on-destroyいますが、 $watch コールバックを繰り返しチェックするのではなく、dom イベントごとに 1 回だけ起動するため、受け入れられた回答よりも優れたパフォーマンスを発揮します。

于 2014-08-25T22:00:36.440 に答える
2

angularの推奨事項ではないと思いますが、要素の初期化時に起動する ng-init を使用できます。

<ul class="unstyled" auto-carousel>
    <li class="slide" ng-if="name" ng-init="recheck()">{{name}}</li>
    <li class="slide" ng-if="email" ng-init="recheck()">{{email}}</li>
</ul>
于 2015-07-14T10:21:22.983 に答える
0

リンク関数内で最初にディレクティブの内容をコンパイルしようとすることができます。例えば:

angular.module('myApp').directive('autoCarousel', ['$compile', function ($compile) {

    return {
        templateUrl: 'views/auto-carousel.html',
        restrict: 'A',
        replace: true,
        link: function (scope, element, attr) {
            $compile(element.contents())(scope);

            // your code goes here
        }
    }
}]);
于 2014-01-24T13:12:19.187 に答える