ページの読み込み時にAngularJSコントローラー関数を実行するにはどうすればよいですか?


359

現在、検索と結果の表示を可能にするAngular.jsページがあります。ユーザーが検索結果をクリックしてから、[戻る]ボタンをクリックします。検索結果を再度表示したいのですが、検索をトリガーして実行する方法がわかりません。詳細は次のとおりです。

  • 私のAngular.jsページは、検索フィールドと検索ボタンを備えた検索ページです。ユーザーは手動でクエリを入力してボタンを押すと、ajaxクエリが実行され、結果が表示されます。検索語でURLを更新します。それはすべてうまくいきます。
  • ユーザーが検索結果をクリックすると、別のページが表示されます-これも正常に機能します。
  • ユーザーが[戻る]ボタンをクリックして、角度検索ページに戻ると、検索語を含む正しいURLが表示されます。すべて正常に動作します。
  • 検索フィールドの値をURLの検索用語にバインドしたので、期待される検索用語が含まれています。すべて正常に動作します。

ユーザーが「検索ボタン」を押す必要なしに検索機能を再実行するにはどうすればよいですか?jqueryの場合、documentready関数で関数を実行します。Angular.jsに相当するものが見当たりません。


使ってるの$routepProvider?これを使用して、検索結果のデータを提供するアプリのサービスに接続します。document.readyjQueryのように考えないでください。現在どのように検索が
関連付け

回答:


430

一方、@ Mark-Rajcokが言ったように、プライベートな内部関数を使用して回避できます。

// at the bottom of your controller
var init = function () {
   // check if there is query in url
   // and fire search in case its value is not empty
};
// and fire it after definition
init();

また、ng-initディレクティブを確認することもできます。実装は次のようになります。

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

ただし、角度のあるドキュメントでは(v1.2以降)使用しないことが示唆さng-initれているため、注意が必要です。ただし、imoはアプリのアーキテクチャに依存します。

ng-initバックエンドから角度付きアプリに値を渡したいときに使用しました:

<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>

6
@デューク、あなたはあなたのコントローラーの一番下にinit()関数の内容を置くことができないのですか?つまり、なぜng-initを使用してinit()関数が必要なのですか?ユーザーが戻るボタンを押すと、ビューを切り替えていると思います。そのため、新しいmyCtrlコントローラーが作成され、実行されます。
Mark Rajcok 2013年

24
このソリューションは機能しますが、ng-initのドキュメントではこれに対してアドバイスしているため、反対票を投じました。具体的には、「ngRepeatの特別なプロパティをエイリアスするためのngInitの唯一の適切な使用は、以下のデモに示されています。この場合に加えて、スコープの値を初期化するには、ngInitではなくコントローラーを使用する必要があります。」
Jason Capriotti

1
コントローラは、htmlが配置された後にインスタンス化されます。
Dmitry Evseev 2014年

3
コントローラが他のページで再利用されているが、特定のページでコントローラを起動したい場合はどうなりますか?
Roberto Linares 14年

3
@RobertoLinares個人的に、ディレクティブは再利用可能な機能のより良い場所だと思います。initパラメータを使用してディレクティブを作成できます:<div smth on-init="doWhatever()">。もちろん、それは特定の使用例に依存します。
Dmitry Evseev 2014年

135

これを試して?

$scope.$on('$viewContentLoaded', function() {
    //call it here
});

5
返信ありがとうございますが、ドミトリーの答えは私が探しているものと完全に一致しました。さらなる調査が$ viewContentLoadedに対して推奨されているようです
Duke Dougal

7
ユースケースは異なります。マークの方法もいつも使っています。
ホログラフィック原理

私のユースケースでは、これは完璧なソリューションでした。ユーザーにコピーを促すために、テキストを自動選択する必要がありました。ページは何度も再読み込み/再訪問される可能性があるため、$ viewContentLoadedは完全に一致しました。ありがとう!
Olga Gnatenko、2015

これが数回実行される可能性はありますか?私はそれを模倣しているように見える行動を
取っ

1
これは私には機能しませんでしたが、$ scope。$ watchは機能しました。主な違いは何ですか?
Burak Tokak

59

私は$viewContentLoaded私のために働くことができなかったのでng-initng-repeat(ドキュメントによると)実際にのみ使用する必要があり、コントローラで直接関数を呼び出すと、コードがまだ定義されていない要素に依存している場合にエラーが発生する可能性があります。

これは私がやっていることであり、私にとってはうまくいきます:

$scope.$on('$routeChangeSuccess', function () {
  // do something
});

を使用してui-routerいる場合を除きます。次にそれは:

$scope.$on('$stateChangeSuccess', function () {
  // do something
});

1
あなたは素晴らしいです、私の友人。
taco

まさに私が必要としたもの。文字通りこれを2日間探していました!
hellojebus

3
$scope.$on('$routeChangeSuccess'urlのパラメータが($locationたとえば)変更されるたびに起動するため、だけを使用できます$scope.$on('$locationChangeSuccess'。ページの読み込み/再読み込み時にトリガーが必要な場合は、$scope.$watch('$viewContentLoaded'ここで提案されているように使用できます。URLパラメータの変更中は起動しません。
神経伝達物質

AngularJS 1.17.2を使用して、コントローラー内で$ routeChangeSuccessが驚くほど機能しました...長いライブadam0101 ...
ArifMustafa 2018

43
angular.element(document).ready(function () {

    // your code here

});

4
受け入れ答えでなければならない、これはそれを行うためのより安全な方法です
Marwen Trabelsi

我々が動作しない場合、これは良いですが$scope、代わりにとの仕事this
Akash

これはどこに行く必要がありますか?テンプレートにありますが、発火していません。
デイブ

この場合、$ documentを挿入するのが最善ではないでしょうか?angular.element($ドキュメント).ready ...
ジェイミー

4
説明をいただければ
幸いです

32

Dimitri's / Mark'sソリューションは私にとっては機能しませんでしたが、$ timeout関数を使用すると、マークアップがレンダリングされた後にのみコードが実行されるように機能するようです。

# Your controller, including $timeout

var $scope.init = function(){
 //your code
}

$timeout($scope.init)

それが役に立てば幸い。


3
最終的に。これは私のために働いた唯一のものです。ありがとう。
zmirc

1
これは機能します。また、var timer = $ timeout($ scope.init、millisecond);がある$ timeout.cancel(timer)でタイムアウトをクリアすることを忘れないでください。初期化が完了すると。また、上記のコードでは$ scopeに 'var' defを含めるべきではないと思います
Emmanuel NK

これは受け入れられる答えになるはずです。それは私のために働いた唯一のものでした(上記のすべての答えを試しました)。iframeの読み込みを待っている場合でも機能します。
hello_fr1end 2017

これでうまくいきます!viewcontentLoadedが機能しませんでした
ダークナイト

28

これは、viewContentLoaded DOMオブジェクトが変化するのを監視して何かをしたい場合に行うことができます。$ scope。$ onの使用も機能しますが、ルーティングに1ページモードがある場合は特に異なります。

 $scope.$watch('$viewContentLoaded', function(){
    // do something
 });

7
具体的には、$ rootScope。$ onの代わりに$ rootScope。$ watchを使用すると、ルートの変更時に起動されないため、初期ページのロードに固有のロジックを使用できます。
csahlman 2014年

19

angularの$ windowオブジェクトを使用できます:

$window.onload = function(e) {
  //your magic here
}


3

そのページに固有のコントローラーがある場合のさらに別の方法:

(function(){
    //code to run
}());

3

$ routeProviderを使用すると、.stateを解決してサービスをブートストラップできます。つまり、サービスを解決した後でのみ、コントローラーとビューをロードします。

UIルート

 .state('nn', {
        url: "/nn",
        templateUrl: "views/home/n.html",
        controller: 'nnCtrl',
        resolve: {
          initialised: function (ourBootstrapService, $q) {

            var deferred = $q.defer();

            ourBootstrapService.init().then(function(initialised) {
              deferred.resolve(initialised);
            });
            return deferred.promise;
          }
        }
      })

サービス

function ourBootstrapService() {

 function init(){ 
    // this is what we need
 }
}

3

Dmitry Evseevの回答が非常に役に立ちました。

ケース1:angularJsのみを使用
するページの読み込み時にメソッドを実行するにng-initは、ビューでを使用し、コントローラーでinitメソッドを宣言できます

このディレクティブは、テンプレートに不要なロジックを追加するために悪用される可能性があります。以下のデモに示されているように、ngRepeatの特殊なプロパティのエイリアスなど、ngInitの適切な使用はごくわずかです。サーバー側のスクリプトを介してデータを注入するため。これらのいくつかのケースに加えて、スコープの値を初期化するには、ngInitではなくコントローラーを使用する必要があります。

HTML:

<div ng-controller="searchController()">
    <!-- renaming view code here, including the search box and the buttons -->
</div>

コントローラ:

app.controller('SearchCtrl', function(){

    var doSearch = function(keyword){
        //Search code here
    }

    doSearch($routeParams.searchKeyword);
})

警告:別の目的で使用される別のビューにこのコントローラーを使用しないでください。検索メソッドもそこで実行されます。

ケース2:Ionicの使用:
上記のコードは機能しますが、次のようにビューキャッシュが無効になっていることを確認しroute.jsてください。

route.js

.state('app', {
    url           : '/search',
    cache         : false, //disable caching of the view here
    templateUrl   : 'templates/search.html'   ,
    controller    : 'SearchCtrl'
  })

お役に立てれば


1
これは1つしかありcache: falseませんでしたが、一番下にありました。私が一番下まで行ってよかったです。
Rani Kheir

3

私は同じ問題を抱えており、このソリューションのみが機能しました(完全なDOMがロードされた後に関数を実行します)。私はこれをスクロールに使用して、ページが読み込まれた後にアンカーします:

angular.element(window.document.body).ready(function () {

                        // Your function that runs after all DOM is loaded

                    });

2

検索結果は、どこからでも使用でき、別のページに移動してもクリアされない共通サービスに保存できます。次に、保存したデータを使用して検索結果を設定し、[戻る]ボタンをクリックします。

function search(searchTerm) {
    // retrieve the data here;
    RetrievedData = CallService();
    CommonFunctionalityService.saveSerachResults(RetrievedData);
} 

バックボタンに

function Backbutton() {
    RetrievedData = CommonFunctionalityService.retrieveResults();
}

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