AngularJSの読み込みが完了したときにイベントを送信する


114

すべてのディレクティブがコンパイル/リンクを行ったときに、ページのロード/ブートストラップの終了を検出するための最良の方法は何だろうと思いました。

すでにそこにイベントはありますか?ブートストラップ関数をオーバーロードする必要がありますか?

回答:


204

ただの直感:ngCloakディレクティブがどのようにそれを行うのか見てみませんか?明らかに、ngCloakディレクティブは、物がロードされた後にコンテンツを表示するように管理します。私はngCloakを見ることは正確な​​答えにつながるでしょう...

1時間後の編集:わかり ました。まあngCloakを調べたところ、本当に短いのです。これが明らかに意味するのは、{{template}}式が評価されるまで(つまり、読み込まれたテンプレート)、ngCloakディレクティブの優れた機能になるまで、コンパイル関数が実行されないことです。

私の教育を受けた推測は、ngCloakと同じ単純さでディレクティブを作成し、コンパイル関数で何でもしたいことを行うことです。:)ディレクティブをアプリのルート要素に配置します。myOnloadのようなディレクティブを呼び出して、属性my-onloadとして使用できます。テンプレートがコンパイルされると、コンパイル関数が実行されます(式が評価され、サブテンプレートが読み込まれます)。

編集、23時間後: わかりました、それで私はいくつかの研究をしました、そして私は私自身の質問もしました。私が尋ねた質問は、この質問に間接的に関連していましたが、偶然にもこの質問を解決する答えに導いてくれました。

答えは、単純なディレクティブを作成し、コードをディレクティブのリンク関数に配置できることです。これは、要素の準備ができている/読み込まれたときに実行されます(ほとんどのユースケースでは、以下で説明します)。コンパイルおよびリンク関数が実行される順序のジョシュの記述に基づいて、

このマークアップがある場合:

<div directive1>
  <div directive2>
    <!-- ... -->
  </div>
</div>

次に、AngularJSはディレクティブ関数を特定の順序で実行してディレクティブを作成します。

directive1: compile
  directive2: compile
directive1: controller
directive1: pre-link
  directive2: controller
  directive2: pre-link
  directive2: post-link
directive1: post-link

デフォルトでは、まっすぐな「リンク」関数はポストリンクなので、外側のdirective1のリンク関数は、内側のdirective2のリンク関数が実行されるまで実行されません。これが、ポストリンクでDOM操作を行うことが安全であると私たちが言う理由です。したがって、元の質問に向かって、動的に挿入されたコンテンツは上記のようにコンパイルする必要がありますが、外部ディレクティブのリンク関数から子ディレクティブの内部htmlにアクセスしても問題はありません。

これから、すべてが準備/コンパイル/リンク/ロードされたときにコードを実行するディレクティブを作成するだけでよいと結論付けることができます。

    app.directive('ngElementReady', [function() {
        return {
            priority: -1000, // a low number so this directive loads after all other directives have loaded. 
            restrict: "A", // attribute only
            link: function($scope, $element, $attributes) {
                console.log(" -- Element ready!");
                // do what you want here.
            }
        };
    }]);

ここでできることは、ngElementReadyディレクティブをアプリのルート要素に配置し、console.logロード時にが起動することです。

<body data-ng-app="MyApp" data-ng-element-ready="">
   ...
   ...
</body>

とても簡単です!単純なディレクティブを作成して使用するだけです。;)

さらにカスタマイズして、式(つまり関数)を実行できるように追加することもでき$scope.$eval($attributes.ngElementReady);ます。

    app.directive('ngElementReady', [function() {
        return {
            priority: Number.MIN_SAFE_INTEGER, // execute last, after all other directives if any.
            restrict: "A",
            link: function($scope, $element, $attributes) {
                $scope.$eval($attributes.ngElementReady); // execute the expression in the attribute.
            }
        };
    }]);

その後、任意の要素で使用できます。

<body data-ng-app="MyApp" data-ng-controller="BodyCtrl" data-ng-element-ready="bodyIsReady()">
    ...
    <div data-ng-element-ready="divIsReady()">...<div>
</body>

要素が存在するスコープ(コントローラー内)で関数(bodyIsReadyやdivIsReadyなど)が定義されていることを確認してください。

警告:これはほとんどの場合に機能すると述べました。ngRepeatやngIfなどの特定のディレクティブを使用するときは注意してください。それらは独自のスコープを作成し、ディレクティブは起動しない可能性があります。たとえば、ngIfもある要素に新しいngElementReadyディレクティブを配置し、ngIfの条件がfalseと評価された場合、ngElementReadyディレクティブは読み込まれません。または、たとえば、ngIncludeディレクティブもある要素に新しいngElementReadyディレクティブを配置した場合、ngIncludeのテンプレートが存在しない場合、ディレクティブは読み込まれません。ディレクティブをすべて同じ要素に置くのではなく、ネストすることで、これらの問題のいくつかを回避できます。たとえば、次のようにします。

<div data-ng-element-ready="divIsReady()">
    <div data-ng-include="non-existent-template.html"></div>
<div>

これの代わりに:

<div data-ng-element-ready="divIsReady()" data-ng-include="non-existent-template.html"></div>

ngElementReadyディレクティブは後者の例でコンパイルされますが、そのリンク関数は実行されません。注:ディレクティブは常にコンパイルされますが、上記のような特定のシナリオによっては、リンク関数が常に実行されるとは限りません。

編集、数分後:

ああ、そして質問に完全に答えるために、あなたは今、$emitまたは$broadcastあなたのイベントを、ng-element-ready属性で実行される式または関数からすることができます。:)例:

<div data-ng-element-ready="$emit('someEvent')">
    ...
<div>

編集、さらに数分後:

@satchmorunの答えも機能しますが、初期ロードの場合のみです。以下は、リンク関数、などを含む、実行される順序を説明する非常に便利なSOの質問ですapp.run。したがって、ユースケースによっては、app.run適切な場合がありますが、特定の要素には適していません。その場合、リンク関数の方が適しています。

編集、5か月後、10月17日8:11 PST:

これは、非同期に読み込まれるパーシャルでは機能しません。パーシャルに簿記を追加する必要があります(たとえば、コンテンツの読み込みが完了したときに各パーシャルを追跡し、イベントを発行して、親スコープが読み込まれたパーシャルの数をカウントし、最終的に必要なことを実行できるようにする方法があります。すべてのパーシャルがロードされた後で行います)。

編集、10月23日午後10:52 PST:

画像が読み込まれたときにいくつかのコードを起動するための簡単なディレクティブを作成しました。

/*
 * This img directive makes it so that if you put a loaded="" attribute on any
 * img element in your app, the expression of that attribute will be evaluated
 * after the images has finished loading. Use this to, for example, remove
 * loading animations after images have finished loading.
 */
  app.directive('img', function() {
    return {
      restrict: 'E',
      link: function($scope, $element, $attributes) {
        $element.bind('load', function() {
          if ($attributes.loaded) {
            $scope.$eval($attributes.loaded);
          }
        });
      }
    };
  });

編集、10月24日午前12:48 PST:

元のngElementReadyディレクティブを改善し、名前をに変更しましたwhenReady

/*
 * The whenReady directive allows you to execute the content of a when-ready
 * attribute after the element is ready (i.e. done loading all sub directives and DOM
 * content except for things that load asynchronously like partials and images).
 *
 * Execute multiple expressions by delimiting them with a semi-colon. If there
 * is more than one expression, and the last expression evaluates to true, then
 * all expressions prior will be evaluated after all text nodes in the element
 * have been interpolated (i.e. {{placeholders}} replaced with actual values). 
 *
 * Caveats: if other directives exists on the same element as this directive
 * and destroy the element thus preventing other directives from loading, using
 * this directive won't work. The optimal way to use this is to put this
 * directive on an outer element.
 */
app.directive('whenReady', ['$interpolate', function($interpolate) {
  return {
    restrict: 'A',
    priority: Number.MIN_SAFE_INTEGER, // execute last, after all other directives if any.
    link: function($scope, $element, $attributes) {
      var expressions = $attributes.whenReady.split(';');
      var waitForInterpolation = false;

      function evalExpressions(expressions) {
        expressions.forEach(function(expression) {
          $scope.$eval(expression);
        });
      }

      if ($attributes.whenReady.trim().length == 0) { return; }

      if (expressions.length > 1) {
        if ($scope.$eval(expressions.pop())) {
          waitForInterpolation = true;
        }
      }

      if (waitForInterpolation) {
        requestAnimationFrame(function checkIfInterpolated() {
          if ($element.text().indexOf($interpolate.startSymbol()) >= 0) { // if the text still has {{placeholders}}
            requestAnimationFrame(checkIfInterpolated);
          }
          else {
            evalExpressions(expressions);
          }
        });
      }
      else {
        evalExpressions(expressions);
      }
    }
  }
}]);

たとえば、次のように使用してsomeFunction、要素が読み込まれ、{{placeholders}}まだ置換されていないときに起動します。

<div when-ready="someFunction()">
  <span ng-repeat="item in items">{{item.property}}</span>
</div>

someFunctionすべてのitem.propertyプレースホルダーが置き換えられる前に呼び出されます。

必要なだけ式true{{placeholders}}評価し、次のように評価されるのを待つ最後の式を作成します。

<div when-ready="someFunction(); anotherFunction(); true">
  <span ng-repeat="item in items">{{item.property}}</span>
</div>

someFunctionそしてanotherFunction後に解雇されます{{placeholders}}置き換えられています。

これは要素が最初にロードされたときにのみ機能し、将来の変更では機能しません。$digestプレースホルダーが最初に置き換えられた後もキープが継続する場合は、期待どおりに機能しない可能性があります($ digestは、データの変更が停止するまで最大10回発生する可能性があります)。ほとんどのユースケースに適しています。

編集、10月31日午後7:26 PST:

了解しました。おそらくこれが最後で最後の更新です。これはおそらく、99.999のユースケースで機能します。

/*
 * The whenReady directive allows you to execute the content of a when-ready
 * attribute after the element is ready (i.e. when it's done loading all sub directives and DOM
 * content). See: /programming/14968690/sending-event-when-angular-js-finished-loading
 *
 * Execute multiple expressions in the when-ready attribute by delimiting them
 * with a semi-colon. when-ready="doThis(); doThat()"
 *
 * Optional: If the value of a wait-for-interpolation attribute on the
 * element evaluates to true, then the expressions in when-ready will be
 * evaluated after all text nodes in the element have been interpolated (i.e.
 * {{placeholders}} have been replaced with actual values).
 *
 * Optional: Use a ready-check attribute to write an expression that
 * specifies what condition is true at any given moment in time when the
 * element is ready. The expression will be evaluated repeatedly until the
 * condition is finally true. The expression is executed with
 * requestAnimationFrame so that it fires at a moment when it is least likely
 * to block rendering of the page.
 *
 * If wait-for-interpolation and ready-check are both supplied, then the
 * when-ready expressions will fire after interpolation is done *and* after
 * the ready-check condition evaluates to true.
 *
 * Caveats: if other directives exists on the same element as this directive
 * and destroy the element thus preventing other directives from loading, using
 * this directive won't work. The optimal way to use this is to put this
 * directive on an outer element.
 */
app.directive('whenReady', ['$interpolate', function($interpolate) {
  return {
    restrict: 'A',
    priority: Number.MIN_SAFE_INTEGER, // execute last, after all other directives if any.
    link: function($scope, $element, $attributes) {
      var expressions = $attributes.whenReady.split(';');
      var waitForInterpolation = false;
      var hasReadyCheckExpression = false;

      function evalExpressions(expressions) {
        expressions.forEach(function(expression) {
          $scope.$eval(expression);
        });
      }

      if ($attributes.whenReady.trim().length === 0) { return; }

    if ($attributes.waitForInterpolation && $scope.$eval($attributes.waitForInterpolation)) {
        waitForInterpolation = true;
    }

      if ($attributes.readyCheck) {
        hasReadyCheckExpression = true;
      }

      if (waitForInterpolation || hasReadyCheckExpression) {
        requestAnimationFrame(function checkIfReady() {
          var isInterpolated = false;
          var isReadyCheckTrue = false;

          if (waitForInterpolation && $element.text().indexOf($interpolate.startSymbol()) >= 0) { // if the text still has {{placeholders}}
            isInterpolated = false;
          }
          else {
            isInterpolated = true;
          }

          if (hasReadyCheckExpression && !$scope.$eval($attributes.readyCheck)) { // if the ready check expression returns false
            isReadyCheckTrue = false;
          }
          else {
            isReadyCheckTrue = true;
          }

          if (isInterpolated && isReadyCheckTrue) { evalExpressions(expressions); }
          else { requestAnimationFrame(checkIfReady); }

        });
      }
      else {
        evalExpressions(expressions);
      }
    }
  };
}]);

このように使う

<div when-ready="isReady()" ready-check="checkIfReady()" wait-for-interpolation="true">
   isReady will fire when this {{placeholder}} has been evaluated
   and when checkIfReady finally returns true. checkIfReady might
   contain code like `$('.some-element').length`.
</div>

もちろん、おそらく最適化できますが、それはそのままにしておきます。requestAnimationFrameは素晴らしいです。


3
これらすべての「data-」接頭辞が本当に煩わしい。自分で使用しないのがうれしいです。
stolsvik 14年

1
@stolsvikへえ、ええ、最新のブラウザでは必要ありません。
trusktr

49
この回答に費やされた時間と労力の量に投票する価値があります。よくやった!
GordyD 2014

8
いい答えですが、すべての「編集」行を削除して、答えを少し再構成することを検討してください。編集履歴は、回答の下部にある[編集済み...]リンクから利用でき、読むときに邪魔になります。
user247702

2
ソースコードは本当に役に立ちます。そして、あなたがそれをnpmで公開できるなら、それは完璧でしょう。本当に良い答え、本当にうまく説明された、これに費やされた努力の量の+1。
tfrascaroli 2016

38

ドキュメントにはangular.Modulerun関数を説明するエントリがあります。

このメソッドを使用して、インジェクターがすべてのモジュールのロードを完了したときに実行する必要がある作業を登録します。

したがって、アプリであるモジュールがある場合:

var app = angular.module('app', [/* module dependencies */]);

モジュールが読み込まれた後、次のものを実行できます:

app.run(function() {
  // Do post-load initialization stuff here
});

編集:救済のための手動初期化

そのためrun、DOMが準備されリンクされたときにが呼び出されないことが指摘されています。$injectorによって参照されるモジュールのng-appがすべての依存関係をロードしたときに呼び出されます。これは、DOMコンパイル手順とは別です。

手動での初期化をもう一度確認しましたが、これでうまくいくようです。

説明のためにフィドルを作成しました

HTMLは単純です。

<html>
    <body>
        <test-directive>This is a test</test-directive>
    </body>
</html>

の欠如に注意してください ng-app。そして、DOM操作を行うディレクティブがあるので、物事の順序とタイミングを確認できます。

いつものように、モジュールが作成されます:

var app = angular.module('app', []);

そしてここにディレクティブがあります:

app.directive('testDirective', function() {
    return {
        restrict: 'E',
        template: '<div class="test-directive"><h1><div ng-transclude></div></h1></div>',
        replace: true,
        transclude: true,
        compile: function() {
            console.log("Compiling test-directive");
            return {
                pre: function() { console.log("Prelink"); },
                post: function() { console.log("Postlink"); }
            };
        }
    };
});

test-directiveタグをdivクラスtest-directiveので置き換え、そのコンテンツをでラップしh1ます。

これらのものがいつ実行されるかを確認できるように、リンク前関数とリンク後関数の両方を返すコンパイル関数を追加しました。

残りのコードは次のとおりです。

// The bootstrapping process

var body = document.getElementsByTagName('body')[0];

// Check that our directive hasn't been compiled

function howmany(classname) {
    return document.getElementsByClassName(classname).length;
}

何かを行う前はtest-directive、DOMにのクラスを持つ要素はなく、完了後は1になるはずです。

console.log('before (should be 0):', howmany('test-directive'));

angular.element(document).ready(function() {
    // Bootstrap the body, which loades the specified modules
    // and compiled the DOM.
    angular.bootstrap(body, ['app']);

    // Our app is loaded and the DOM is compiled
    console.log('after (should be 1):', howmany('test-directive'));
});

とても簡単です。ドキュメントの準備ができたら、angular.bootstrapアプリのルート要素とモジュール名の配列を使用して呼び出します。

実際、モジュールに関数をアタッチするとrunappにと、コンパイルが行われる前に実行されることがわかります。

フィドルを実行してコンソールを見ると、次のように表示されます。

before (should be 0): 0 
Compiling test-directive 
Prelink
Postlink
after (should be 1): 1 <--- success!

2
@satchmorunに感謝!しかし、run()はリンク部分の終わりの前に実行されます-いくつかのconsole.logsでそれを確認しただけです。
リオール

気になった...私はいくつかのjQuery DOMプラグインを実装するために起動するディレクティブを持っています。ディレクティブのrun前に起動し、起動時にHTMLがすべてではありません
charlietfl

@charlietfl-私は手動のブートストラップを少し掘り下げましたが、実際には、質問が探しているものを取得するためのかなり簡単な方法です。元の回答にかなり長い編集を追加しました。
satchmorun 2013

5
私は$timeout( initMyPlugins,0)私のディレクティブ内の作品を使用して、必要なすべてのhtmlがそこにあることを発見しました
charlietfl

:@satchmorun、このフォローアップを参照stackoverflow.com/questions/14989161/...
LIOR

16

Angularは、ページの読み込みが完了したことを通知する方法を提供していません。これは、「終了」がアプリケーションによって異なるためと考えられます。たとえば、パーシャルの階層ツリーがある場合、一方が他方をロードします。「終了」は、それらのすべてがロードされたことを意味します。どのフレームワークでも、コードを分析し、すべてが完了した、またはまだ待機していることを理解するのは困難です。そのためには、アプリケーション固有のロジックを提供して、それを確認および決定する必要があります。


14

角度の初期化がいつ完了したかを評価するのに比較的正確な解決策を考え出しました。

ディレクティブは次のとおりです。

.directive('initialisation',['$rootScope',function($rootScope) {
            return {
                restrict: 'A',
                link: function($scope) {
                    var to;
                    var listener = $scope.$watch(function() {
                        clearTimeout(to);
                        to = setTimeout(function () {
                            console.log('initialised');
                            listener();
                            $rootScope.$broadcast('initialised');
                        }, 50);
                    });
                }
            };
        }]);

次に、属性としてbody要素に追加し、使用するためにリッスンすることができます$scope.$on('initialised', fn)

これは、$ digestサイクルがなくなるとアプリケーションが初期化されると想定して機能します。$ watchはすべてのダイジェストサイクルで呼び出されるため、タイマーが開始されます(setTimeoutは$ timeoutではなく、新しいダイジェストサイクルはトリガーされません)。タイムアウト内にダイジェストサイクルが発生しない場合、アプリケーションは初期化されていると見なされます。

satchmorunsソリューションほど正確ではないことは明らかですが(ダイジェストサイクルがタイムアウトよりも長くなる可能性があるため)、私のソリューションではモジュールを追跡する必要がないため、管理が非常に簡単になります(特に大規模なプロジェクトの場合)。 )。とにかく、私の要件には十分正確であるようです。それが役に立てば幸い。


優れたソリューション。1つまたは2つの圧縮ファイル内のすべてのコードが非常にうまく機能するプロジェクトの場合。
merqlove 2014

1
これは素晴らしいソリューションです.jqueryに多くのコードがあり、コードを段階的に角度に変換しようとしている場合、これは完全に理にかなっています。
Mangesh Pimpalkar 14

11

Angular UIルーターを使用している場合は、$viewContentLoadedイベントをリッスンできます。

"$ viewContentLoaded-ビューが読み込まれると、DOMがレンダリングされた後に発生します。ビューの '$ scope'がイベントを発行します。" - リンク

$scope.$on('$viewContentLoaded', 
function(event){ ... });

3
$ scope。$ watch( '$ viewContentLoaded'、function()は私にとってトリックを作りました
Louis XIV

2
「あなたがすべき」に反対票を投じました。「Angularの代わりにReactを使用している場合(そうする必要があります)...」と言ったらどうなりますか?このエコシステムに私見を持たせるのは、あまり態度ではありません。
Valentin Waeselynck、2016

@ValentinWaeselynckあなたは絶対的に正しいです。私は自分の偏見を取り除くために私の答えを編集しました。
ジョーダンスコレ

1
私のために働いた!ありがとうございました。実際にrun関数に追加してから、$ scopeを$ rootScopeに変更しました。
JDaviesは2016年

2
Angular Universityが別の答えで指摘したように、$ viewContentLoadedは元々存在しなかった可能性がありますが、組み込みのngRouteプロバイダーでまったく同じように機能するようになりました。それを念頭に置いて、これは多くの(ほとんどの?)読者が探している、素早く、シンプルで、読みやすい答えだと思います。
Kevin Crumley、2016

3

私はJQueryで角度のDOM操作を観察し、アプリの仕上げ(アプリの抽象に必要な事前定義された満足のいく状況の一種)を設定しました。たとえば、ng-repeaterが7つの結果を生成し、そこにこの目的のために、setIntervalを使用して監視関数を設定します。

$(document).ready(function(){

  var interval = setInterval(function(){

  if($("article").size() == 7){
     myFunction();
     clearInterval(interval);
  }

  },50);

});

3
私はこれをしません。間隔を使用して発生していることを確認することは良い方法ではなく、拡張性がありません。また、発生させる他の方法もあります。タイマーは、コンテンツまたは結果の準備ができたときに「推測」するためではなく、特定の期間後に発生する必要がある具体的なタスクを実行するためのものです。
dudewad 2014

アンギュラープラットフォームに対してjqueryタイマーを使用すると生産性が低下することは言うまでもありません。アンギュラーにはタイムアウトクラスがあり、それを使用しないと2つのフレームワークにまたがってしまい、すぐに混乱してしまいます。
dudewad 14

3

ngRouteモジュールを使用しない場合、つまり$ viewContentLoadedイベントがない場合。

別のディレクティブメソッドを使用できます。

    angular.module('someModule')
        .directive('someDirective', someDirective);

    someDirective.$inject = ['$rootScope', '$timeout']; //Inject services

    function someDirective($rootScope, $timeout){
        return {
            restrict: "A",
            priority: Number.MIN_SAFE_INTEGER, //Lowest priority
            link    : function(scope, element, attr){
                $timeout(
                    function(){
                        $rootScope.$emit("Some:event");
                    }
                );
            }
        };
    }

したがって、trusktrの回答によると、優先順位は最も低くなります。さらに$ timeoutは、Angularがコールバックの実行前にイベントループ全体を実行するようにします。

$ rootScopeを使用。これは、ディレクティブをアプリケーションの任意のスコープに配置し、必要なリスナーのみに通知できるためです。

$ rootScope。$ emitは、すべての$ rootScope。$ onリスナーに対してのみイベントを発生させます。興味深い部分は、$ rootScope。$ broadcastがすべての$ rootScope。$ onおよび$ scope。$ onリスナーソースに通知することです。


2

AngularチームとこのGithubの問題によると:

$ viewContentLoadedイベントと$ includeContentLoadedイベントがあり、それぞれng-viewとng-includeで発行されます。これは、コンパイルがいつ完了したかを知ることができる限り近いと思います。

これに基づいて、これは現在信頼できる方法で行うこと不可能であると思われます。そうでなければ、Angularはそのままイベントを提供していたでしょう。

アプリのブートストラップは、ルートスコープでダイジェストサイクルを実行することを意味し、ダイジェストサイクル終了イベントもありません。

Angular 2 設計ドキュメントによると:

複数のダイジェストがあるため、モデルが安定していることを判断してコンポーネントに通知することはできません。これは、通知によってデータがさらに変更され、バインディングプロセスが再開される可能性があるためです。

これによると、これが不可能であるという事実は、Angular 2で書き換えを行うことを決定した理由の1つです。


2

ルーティング経由で入ってくるメインのパーシャルの後でロードされるフラグメントがありました。

そのサブパーシャルが読み込まれた後に関数を実行する必要があり、新しいディレクティブを記述したくなかったので、あなたは生意気なものを使用できると考えました ngIf

親部分のコントローラー:

$scope.subIsLoaded = function() { /*do stuff*/; return true; };

サブパーシャルのHTML

<element ng-if="subIsLoaded()"><!-- more html --></element>

1

サーバー側データ(JSP、PHP)でJSを生成する場合は、ロジックをサービスに追加できます。これは、コントローラーがロードされるときに自動的にロードされます。

さらに、すべてのディレクティブのコンパイル/リンクが完了したときに反応したい場合は、上記の適切なソリューションを初期化ロジックに追加できます。

module.factory('YourControllerInitService', function() {

    // add your initialization logic here

    // return empty service, because it will not be used
    return {};
});


module.controller('YourController', function (YourControllerInitService) {
});

0

これらはすべて素晴らしいソリューションですが、現在ルーティングを使用している場合は、このソリューションが最も簡単で必要なコードの量が最も少ないことがわかりました。'resolve'プロパティを使用して、ルートがトリガーされる前にpromiseの完了を待機します。例えば

$routeProvider
.when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        message: function(messageService){
            return messageService.getMessage();
    }
}

})

完全なドキュメントについては、ここをクリックしてください-K. Scott Allenの功績


0

この例で私はあなたを助けることができるかもしれません

カスタムのファンシーボックスに、補間された値でコンテンツを表示します。

サービスでは、「オープン」fancyboxメソッドで、私はやります

open: function(html, $compile) {
        var el = angular.element(html);
     var compiledEl = $compile(el);
        $.fancybox.open(el); 
      }

$ compileはコンパイルされたデータを返します。コンパイルしたデータを確認できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.