19119


自作ディレクティブで親スコープ内変数の変更を検知し、他の処理を実行したいと思っています。  
下記の例で実現したいのは、`tags1`の変更を検知してコンソールログを出力するものです。  
index.html内の`<sample-directive>`をmyapp.jsで定義しています。  
また、要素のドラッグ&ドロップ移動に[UI.Sortable directive](https://github.com/angular-ui/ui-
sortable)を使用しています  
ブラウザでの読み込み時、`console.log("tag1_change");`が実行されます。  
それ以降、データ１の要素をデータ２に移動させた時、`tags1`の配列が変更されることは確認できるのですが、ディレクティブでは変更を検知しません。

わかる方いらっしゃいましたら解決方法をご教授願います。

index.html

[code]

    <html lang="ja">
    <head>
        <meta charset="utf-8">
        <style>
            .tags{
                border: 1px solid #CCC;
                min-height: 10px;
                cursor: move;
                list-style: none;
            }
        </style>
    </head>
    <body ng-app="App" ng-controller="AppCtrl">
        <sample-directive></sample-directive><!--tags1値をウォッチしたい -->
        <div>
            <p>
                グループ１
            </p>
            <ul class="tags" id="tags1" ng-model="tags1" ui-sortable="sortableOptions">
                <li ng-repeat="item in tags1">{{item.value}}</li>
            </ul>
        </div>
        <div>
            <p>
                グループ２
            </p>
            <ul class="tags" id="tags2" ng-model="tags2" ui-sortable="sortableOptions">
                <li ng-repeat="item in tags2">{{item.value}}</li>
            </ul>
        </div>
        tags1:{{tags1|json}}
        <script src="http://d3js.org/d3.v2.js"></script>
        <script src="http://cdn.jsdelivr.net/g/jquery@1,jquery.ui@1.10%28jquery.ui.core.min.js+jquery.ui.widget.min.js+jquery.ui.mouse.min.js+jquery.ui.sortable.min.js%29,angularjs@1.2,angular.ui-sortable"></script>
        <script src="myapp.js"></script>
    </body>
    </html>
    
[/code]

myapp.js

[code]

    var tags1 = [{
        "id": "1",
        "value": "データ1"
    }, {
        "id": "2",
        "value": "データ2"
    }, {
        "id": "3",
        "value": "データ3"
    }];
    var tags2 = [];
    
    var HcApp = angular.module('App', ['ui.sortable'])
        .controller('AppCtrl', ['$scope', function($scope) {
    
            $scope.tags1 = tags1;
            $scope.tags2 = tags2;
    
            $scope.sortableOptions = {
                connectWith: ".tags",
            };
        }]);
    
    HcApp.directive('sampleDirective', function() {
        return {
            restrict: 'E',
            link: function(scope, element, attrs) {
                //tags1を監視したい
                scope.$watch('tags1', function(newVal, oldVal) {
                    console.log("tag1_change");
                    if (newVal === oldVal) {
                        return;
                    }
                    if (newVal) {
                        console.log("tag1_change_if");
                    } else {
                        console.log("tag1_change_else");
                    }
                });
            }
        }
    });
    
[/code]


CC BY-SA 3.0
2015-11-21T01:20:17.613
19106
2015-11-21T06:08:47.853
2015-11-21T01:33:42.830
13045
13045
question
javascript angularjs
angular.jsのディレクティブで定義した$watch式がトリガされない。


`$watch`の第3引数`objectEquality`に`true`を設定すると配列の変化を監視することができます。  
デフォルトは`false`なので監視されません。

英語版の方にも同じような質問があります。

[AngularJS : $watch an
object](https://stackoverflow.com/questions/19455501/angularjs-watch-an-
object)

[code]

    scope.$watch('tags1', function(newVal, oldVal) {
        console.log("tag1_change");
        if (newVal === oldVal) {
            return;
        }
        if (newVal) {
            console.log("tag1_change_if");
        } else {
            console.log("tag1_change_else");
        }
    }, true);
    
[/code]


CC BY-SA 3.0
2015-11-21T05:36:06.183
19119
2015-11-21T05:36:06.183
2017-05-23T12:38:55.307
-1
9566
19106
answer


$watchはインスタンスが変更された事を監視するものです。  
その為、配列の中身をいくら変えようがtags1に入れている配列（インスタンス）に変わりはありませんので動作しません。

配列の追加・削除を監視するには、$watchCollectionで行います。

[code]

    scope.$watchCollection('tags1', function(newVal, oldVal) {
    });
    
[/code]


CC BY-SA 3.0
2015-11-21T06:08:47.853
19120
2015-11-21T06:08:47.853
4191
19106
answer