2

ドキュメントに示されているほとんどの例のように、グローバル関数になるように角度コントローラーをセットアップしています。Angularエンジンがhtmlのコントローラータグを認識したときにコントローラークラスが呼び出されていると思います。

私の問題は、コントローラーにパラメーターを渡したいのですが、初期化していないため、その方法がわかりません。ng-initの使用を示唆するいくつかの回答があります。しかし、私のパラメーターは簡単な文字列ではありません-それは私のjsの別の(角度のない)部分によってロードされている複雑なオブジェクトです。また、ロード時に利用することはできませんが、実行には時間がかかります。

したがって、最終的にロードが完了したときに、コントローラーがオブジェクトと対話できるように、このオブジェクトをコントローラー(またはスコープ)に渡す方法が必要です。これは可能ですか?

4

2 に答える 2

8

これには、サービスまたはファクトリを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を呼び出すと、登録されているすべてのスコープをループし、それぞれに対してダイジェストを実行して、スコープが更新されていることを確認します。

于 2013-02-19T00:11:09.013 に答える
5

非角度JavaScriptでは、次のようにDOM要素に関連付けられたスコープにアクセスできます。

angular.element(someDomElement).scope().someControllerFunction(delayedData);

jQueryセレクターなどでsomeDomElementを見つけることができると思います。

于 2013-02-18T21:16:26.213 に答える