8

これはばかげた質問のように思えるかもしれませんが、ページの DOM 全体を監視し、変更されたときに再コンパイルする方法を知る必要があります。基本的に、これは AngularJS がデータバインディングを使用してデフォルトで行うことですが、バインディングだけでなく、DOM 内の何かが変更されるたびにこれを行う必要があります。その理由は、HTML、Javascript、および PHP で完全に構築されたアプリを持っているからです。これは単一ページのアプリケーションで、メイン ページがあり、そのページ内の DIV ラッパーに PHP を挿入します。

いくつかの変更を加えたいが、元のコードから完全に分離したままにしたい。これを行うには、独自の DOM 構造を持つ新しい PHP ファイルが挿入されるたびに、DOM を再コンパイルできる必要があります。私がこれまでに持っているものは機能していないようです。

app.directive("watch", function () {
    return function (scope, element, attr) {
        scope.$watch("watch", function(oldValue, newValue) {
            if(newValue) {
                console.log("there is a new value");
                console.log("the new value is " + newValue);
             }
         });
     }
});

タグに watch 属性を追加しました<body>が、dom が変更されても何もログに記録されないため、機能していないようです。最終的には、console.log を $compile に置き換えたいのですが、最初にウォッチを機能させる必要があります。誰かが私が間違っていることを指摘できますか?

4

5 に答える 5

32

悪い考えですが、私はあなたに冗談を言います。

したがって、上記のコメントで述べたように、やろうとしていることを実行するのは悪い考えです。とはいえ、それでもこの方法を使いたい場合は$watch、最初のパラメーターとして関数を渡すことで、ほぼ何でもできます。

<body>以下のコードは、タグ内の HTML が変更されたかどうかを確認します。これは恐ろしい考えであることに注意してください。

$scope.$watch(function () {
   return document.body.innerHTML;
}, function(val) {
   //TODO: write code here, slit wrists, etc. etc.
});

上記のウォッチは、HTML 内の何かが変更されるたびに起動します。

  • 入力で値が変化したとき
  • ドロップダウンで選択が変更されたとき
  • html のいずれかの要素で属性が変更されたとき。

追加情報:現時点では、多くのブラウザーで、読み込まれた新しい DOM 要素を監視する良い方法はありません。最良の方法は、新しい DOM 要素が追加された時点で何かをトリガーすることです。

于 2013-10-10T19:40:04.677 に答える
11

Steinway Wu が述べたように、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:46:56.500 に答える
2

小さなユーティリティ サービスを作成しました

ここにコードがあります

私たちはGenericService.jsこれを持っています

angular.module('GenericServiceModule', [])
    .factory('$utilsService', function () {

        var utilService = {};

        utilService.observeDomChange = function (domElement, doThisOnChange, observationOptions) {
            var defaultOptions = {
                // attributes: true, // attribute changes will be observed | on add/remove/change attributes
                // attributeOldValue: true, // will show oldValue of attribute | on add/remove/change attributes | default: null
                // we need this because in .find() sizzle modifies id temporarily, https://github.com/jquery/jquery/issues/2620
                //attributeFilter: ['style'], // filter for attributes | array of attributes that should be observed, in this case only style

                // characterData: true, // data changes will be observed | on add/remove/change characterData
                // characterDataOldValue: true, // will show OldValue of characterData | on add/remove/change characterData | default: null

                childList: true, // target childs will be observed | on add/remove
                subtree: true // target childs will be observed | on attributes/characterData changes if they observed on target

            };
            var options = observationOptions || defaultOptions;

            var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
            var observer = new MutationObserver(function anElementIWatchChanged(mutations) {
                doThisOnChange();
            });

            // removing the dom element won't be triggered
            observer.observe(domElement, options);
        };

        return utilService;
    });

そして単にあなたはそれを次のように使うことができます

$utilsService.observeDomChange($element[0], doSomething());

これは使用例です

angular.module(
...
.directive('myCustomDirective', function ($utilsService) {
    return {
        restrict: 'A',
        //...
        controller: function ($scope, $element) {
            //...
            $scope.$on('$viewContentLoaded', function (event, viewName) {
                $utilsService.observeDomChange($element[0], doSomething());
            }
        }
    }
}
于 2018-07-22T11:23:44.907 に答える
0

ここ (Mutation Events)で述べたように、 のような DOM 突然変異イベントのリスナーを追加できますDOMSubtreeModified

例えばelement.addEventListener("DOMSubtreeModified", function (ev) {...}, false)

アップデート

実際、彼らは代わりにMutation Observerを使用することを推奨しています。

于 2014-06-19T17:09:11.183 に答える