これには、サービスまたはファクトリをpromiseと組み合わせて使用できます。
promiseを返すファクトリをセットアップし、promiseを解決するためのグローバル関数(サードパーティのJSからアクセス可能)を作成できます。
$rootScope.$apply()
呼び出しに注意してください。Angularはサイクルthen
までpromiseの関数を呼び出しません。ドキュメント$apply
を参照してください。$q
app.factory('fromoutside', function($window, $q, $rootScope) {
var deferred = $q.defer();
$window.injectIntoAngularWorld = function(obj) {
deferred.resolve(obj);
$rootScope.$apply();
};
return deferred.promise;
});
次に、コントローラーで、fromoutside
サービスを要求し、到着時にデータにバインドできます。
app.controller('main', function($scope, fromoutside) {
fromoutside.then(function(obj) {
$scope.data = obj;
});
});
そして、Angularの外のどこか:
setTimeout(function() {
window.injectIntoAngularWorld({
A: 1,
B: 2,
C: 3
});
}, 2000);
これがこのフィドルです。
個人的には、これはDOMを介してAngularコントローラーに到達するよりも少しクリーンだと思います。
編集:別のアプローチ
Mark Rajcokはコメントで、これを変更してデータを複数回取得できるかどうかを尋ねました。
現在、データを複数回取得することは、増分更新、オブジェクト自体の変更、またはその他のことを意味する可能性があります。しかし、発生する必要がある主なことは、データをAngularの世界に取り込み、次に適切な角度$digest
のスコープを取得してそれらを実行することです。
このフィドルでは、Angularの外側から配列の更新を取得している可能性がある場合の1つの方法を示しました。
上記のpromiseの例と同様のトリックを使用します。
主な工場は次のとおりです。
app.factory('data', function($window) {
var items = [];
var scopes = [];
$window.addItem = function(item) {
items.push(item);
angular.forEach(scopes, function(scope) {
scope.$digest();
});
};
return {
items: items,
register: function(scope) { scopes.push(scope); }
};
前の例のように、関数をサービスにアタッチし$window
ます(グローバルに公開します)。register
新しいビットは、更新をdata
必要とするコントローラーが自分自身を登録するために使用する必要がある関数を公開しています。
外部JSがAngularを呼び出すと、登録されているすべてのスコープをループし、それぞれに対してダイジェストを実行して、スコープが更新されていることを確認します。