内部でデータを操作(データの挿入や削除など)するときにAngularディレクティブで$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
セットに正しく挿入されています。私が設定したテーブルは、「追加」ボタンを押すたびに更新されます。
<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!"
というメッセージが表示されますが、「追加」ボタンを押してもその後は表示されません。
まったく新しいデータセットをdata
オブジェクトに割り当てるのではなく、単にdata
オブジェクトにオブジェクトを追加または削除するときに$watch
イベントを発生させる方法を教えてください。
あなたはディープオブジェクトダーティチェックを有効にする必要があります。デフォルトでは、angleはあなたが見ているトップレベルの変数の参照のみをチェックします。
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が導入されました $ watchCollection
Shallowはオブジェクトのプロパティを監視し、いずれかのプロパティが変更されるたびに起動します(配列の場合は配列項目を監視することを意味し、オブジェクトマップの場合はプロパティを監視することを意味します)
scope.$watchCollection('val.children', function(newValue, oldValue) {});
深くデータをトリガーする場合は、リスナーの3番目の引数true
を渡す必要があります。デフォルトではfalse
であり、関数がトリガーされるのは、 変数はフィールドではなく変更されます。
利用可能になったデータをプロットするためにjqplotを使用するディレクティブの私のバージョン:
app.directive('lineChart', function() {
$.jqplot.config.enablePlugins = true;
return function(scope, element, attrs) {
scope.$watch(attrs.lineChart, function(newValue, oldValue) {
if (newValue) {
// alert(scope.$eval(attrs.lineChart));
var plot = $.jqplot(element[0].id, scope.$eval(attrs.lineChart), scope.$eval(attrs.options));
}
});
}
});