11

私がやろうとしていることは、おそらく良い習慣とは見なされていないということから始めましょう。ただし、小さな増分ステップで大規模な Web アプリを AngularJs に移行するには、このようなことを行う必要があります。

やってみた

 $scope.$watch(function () { return myVar; }, function (n, old) {
                    alert(n + ' ' + old);
                });

myVar はグローバル変数です (ウィンドウで定義)

そして、コンソールから myVar を変更します。ただし、ウォッチャーを最初にセットアップするときにのみ起動します。

コントローラー内から myVar を更新すると機能します ( http://jsfiddle.net/rasmusvhansen/vsDXz/3/を参照してください。ただし、レガシー JavaScript から更新された場合は機能しません)。

これを達成する方法はありますか?

更新 レガシーコードが完全に立ち入り禁止の場合、アンダースの答えが好きです。ただし、現時点では、機能しているように見え、毎秒起動するタイマーが含まれていないこのアプローチを見ています。

// In legacy code when changing stuff    
$('.angular-component').each(function () {
        $(this).scope().$broadcast('changed');
});

// In angular
$scope.$on('changed', function () {
    $scope.reactToChange();
});

私は別のソリューションを使用しますが、Anders のソリューションは記載されている問題を正しく解決しているため、Anders にポイントを与えます。

4

1 に答える 1

12

ここでの問題は、おそらくmyVarAngularの世界の外から変更していることです。Angularは、ダイジェストをトリガーする必要のあるアプリケーションで何かが発生した場合にのみ、ダイジェストサイクル/ダーティチェックを常に実行するわけではありません。たとえば、Angularが認識しているDOMイベントなどです。したがって、myVar変更された場合でも、何も起こらなかったため(少なくとも、Angularが知っていること)、Angularは新しいダイジェストサイクルを開始する理由を認識しません。

したがって、時計を起動するには、変更時にAngularにダイジェストを実行させる必要がありますmyVar。しかし、それは少し面倒です。次のようなグローバルな監視可能なオブジェクトを作成する方がよいと思います。

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
    <script>
    // Outside of Angular
    window.myVar = {prop: "value1"};
    var myVarWatch = (function() {
        var watches = {};

        return {
            watch: function(callback) {
                var id = Math.random().toString();
                watches[id] = callback;

                // Return a function that removes the listener
                return function() {
                    watches[id] = null;
                    delete watches[id];
                }
            },
            trigger: function() {
                for (var k in watches) {
                    watches[k](window.myVar);
                }
            }
        }
    })();

    setTimeout(function() {
        window.myVar.prop = "new value";
        myVarWatch.trigger();
    }, 1000);

    // Inside of Angular
    angular.module('myApp', []).controller('Ctrl', function($scope) {
        var unbind = myVarWatch.watch(function(newVal) {
            console.log("the value changed!", newVal);
        });

        // Unbind the listener when the scope is destroyed
        $scope.$on('$destroy', unbind);
    });
    </script>
</head>
<body ng-controller="Ctrl">

</body>
</html>
于 2013-03-08T13:25:02.213 に答える