web-dev-qa-db-ja.com

AngularJSロードサービスは、コントローラーを呼び出してレンダリングします

私の問題は、コントローラーが呼び出されてテンプレートがレンダリングされる前にサービスをロードする必要があることです。 http://jsfiddle.net/g75XQ/2/

Html:

<div ng-app="app" ng-controller="root">
    <h3>Do not render this before user has loaded</h3>            
    {{user}}
</div>
​

JavaScript:

angular.module('app', []).
factory('user',function($timeout,$q){
    var user = {};            
    $timeout(function(){//Simulate a request
        user.name = "Jossi";
    },1000);
    return user;
}).
controller('root',function($scope,user){

    alert("Do not alert before user has loaded");
    $scope.user = user;

});
​

21
Jossi

ng-app属性を使用した自動初期化の代わりに、 手動初期化 を使用して、angular appの初期化を延期できます。

// define some service that has `$window` injected and read your data from it
angular.service('myService', ['$window', ($window) =>({   
      getData() {
          return $window.myData;
      }
}))    

const callService = (cb) => {
   $.ajax(...).success((data)=>{
         window.myData = data;
         cb(data)
   })
}

// init angular app 
angular.element(document).ready(function() {
       callService(function (data) {
          doSomething(data);
          angular.bootstrap(document);
       });
});

ここで、callServiceは、AJAX呼び出しを実行し、成功コールバックを受け入れる関数です。これにより、init angular app。

また、ngCloakディレクティブもチェックしてください。おそらく必要なものはすべて揃っているからです。

または、 ngRoute を使用する場合、resolveプロパティを使用できます。そのため、@ honkskilletの回答を確認できます

14
vittore

手動でブートストラップするよりも優れています(常に悪い考えではありません)。

angular.module('myApp', ['app.services'])
   .run(function(myservice) {
      //stuff here.
   });
9
davidjnelson

コメントで述べたように、コントローラーでアンロードされた状態を処理する方がはるかに簡単です。これを非常に簡単にするために、$ qの恩恵を受けることができます: http://jsfiddle.net/g/g75XQ/4 /

ユーザーが読み込まれたときにコントローラーで何かを作成したい場合: http://jsfiddle.net/g/g75XQ/6/

編集:データがロードされるまでルートの変更を遅らせるには、この答えを見てください: フリッカーを防ぐためにモデルがロードされるまでAngularJSルートの変更を遅らせる

4
Guillaume86

これを達成する正しい方法は、ルート定義で解決プロパティを使用することです: http://docs.angularjs.org/api/ngRoute.$routeProvider を参照してください

次に、$ qサービスを使用してプロミスを作成して返します。また、$ httpを使用して要求を行い、応答時に、約束を解決します。

そのようにして、ルートが解決され、コントローラーがロードされると、promiseの結果は既に使用可能になり、ちらつきは発生しません。

4
Ciul

.config $ routeProviderで解決を使用できます。 (ここにあるように)約束が返された場合、ルートは解決されるか拒否されるまでロードされません。また、戻り値は、コントローラー(この場合はSomert)に注入できます。

angular.module('somertApp')
  .config(function($routeProvider) {
    $routeProvider
      .when('/home/:userName', {
        /**/
        resolve: {
          Somert: function($q, $location, Somert) {
            var deferred = $q.defer();
            Somert.get(function(somertVal) {
              if (somertVal) {
                deferred.resolve(somertVal);
              } else {
                deferred.resolve();
                $location.path('/error/'); //or somehow handle not getting
              }
            });
            return deferred.promise;
          },
        },
      });
  });
1
honkskillet

いくつかの方法があり、他の方法より高度な方法もありますが、あなたの場合、ng-hideがトリックを行います。 http://jsfiddle.net/roytruelove/g75XQ/3/ を参照してください

0
Roy Truelove