1. ホーム
  2. javascript

[解決済み] Angularディレクティブのデータ変更に対する$watch'ing

2022-06-29 15:43:22

質問

どのようにすれば $watch 変数をトリガーし、その変数に新しいオブジェクトを割り当てないようにするにはどうしたらよいでしょうか?

私は現在、JSONファイルから読み込まれている単純なデータセットを持っています。 私のAngularコントローラはこれを行うだけでなく、いくつかの関数を定義しています。

App.controller('AppCtrl', function AppCtrl($scope, JsonService) {
    // load the initial data model
    if (!$scope.data) {
        JsonService.getData(function(data) {
            $scope.data = data;
            $scope.records = data.children.length;
        });
    } else {
        console.log("I have data already... " + $scope.data);
    }

    // adds a resource to the 'data' object
    $scope.add = function() {
        $scope.data.children.push({ "name": "!Insert This!" });
    };

    // removes the resource from the 'data' object
    $scope.remove = function(resource) {
        console.log("I'm going to remove this!");
        console.log(resource);
    };

    $scope.highlight = function() {

    };
});

私の場合は <button> を適切に呼び出した $scope.add 関数が適切に呼び出され、新しいオブジェクトが適切に $scope.data に正しく挿入されます。 私がセットアップしたテーブルは、"add" ボタンを押すたびに更新されます。

<table class="table table-striped table-condensed">
  <tbody>
    <tr ng-repeat="child in data.children | filter:search | orderBy:'name'">
      <td><input type="checkbox"></td>
      <td>{{child.name}}</td>
      <td><button class="btn btn-small" ng-click="remove(child)" ng-mouseover="highlight()"><i class="icon-remove-sign"></i> remove</button></td>
    </tr>
  </tbody>
</table>

しかし、私が設定したディレクティブは、監視するために $scope.data を監視するように設定したディレクティブは、 このようなことが起こったときに起動されません。

HTMLでタグを定義しています。

<d3-visualization val="data"></d3-visualization>

これは、以下のディレクティブと関連しています (質問の正しさのために切り詰めています)。

App.directive('d3Visualization', function() {
    return {
        restrict: 'E',
        scope: {
            val: '='
        },
        link: function(scope, element, attrs) {
            scope.$watch('val', function(newValue, oldValue) {
                if (newValue)
                    console.log("I see a data change!");
            });
        }
    }
});

を取得します。 "I see a data change!" のメッセージが表示されますが、quot;add"ボタンを押しても表示されません。

どうすれば $watch にオブジェクトを追加したり削除したりするだけなのに、どのようにして data オブジェクトに割り当てる新しいデータセットを取得するのではありません。 data オブジェクトに割り当てるための、まったく新しいデータセットを取得しないのですか?

どのように解決するのですか?

深いオブジェクトのダーティチェックを有効にする必要があります。 デフォルトでは、angularはウォッチしているトップレベルの変数の参照のみをチェックします。

App.directive('d3Visualization', function() {
    return {
        restrict: 'E',
        scope: {
            val: '='
        },
        link: function(scope, element, attrs) {
            scope.$watch('val', function(newValue, oldValue) {
                if (newValue)
                    console.log("I see a data change!");
            }, true);
        }
    }
});

見る スコープ . watch関数の第3パラメータをtrueに設定すると、ディープダーティチェックが可能になります。

ディープダーティチェックは 高価 . そのため、もし子配列を見るだけなら data を見るだけなら、直接その変数を見ればいいのです。

scope.$watch('val.children', function(newValue, oldValue) {}, true);

バージョン1.2.x導入 ウォッチコレクション

Shallow はオブジェクトのプロパティを監視し、プロパティが変更されるたびに処理を開始します (配列の場合、これは配列の項目を監視することを意味します; オブジェクトマップの場合、これはプロパティを監視することを意味します)。

scope.$watchCollection('val.children', function(newValue, oldValue) {});