web-dev-qa-db-ja.com

コントローラーをロードする前に、AngularJSサービスがデータを強制的に返す

Angularには、APIを使用してユーザー情報を取得し、それをコントローラーに提供するサービスがあります。次のように設定されています。

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
  .service('userInfo', function($http, $cookies){
    $http.get('/api/users/' + $cookies.id).
    success(function(data) {
      var userInfo = data.user[0];

      return userInfo;
    });
  }). // other stuff comes after this

私のコントローラーには、次のように組み込みます。

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    $scope.user = userInfo;
    console.log('user info is')
    console.log(userInfo);

これはデータを返していませんが、同じサービス関数をコントローラー自体に入れると、うまく戻ります。ここで何が欠けていますか?以前にAngularでDI/Servicesを使用したことがないため、どこかで単純な間違いになる可能性があります。

サービスがデータを返すことを確認する必要がありますbeforeコントローラーがロードされます。どうすればこれを達成できますか

34
JVG

次のような約束を返すようにファクトリを作成できます。

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
    .service('userInfo', function ($http, $cookies) {
    var promise = $http.get('/api/users/' + $cookies.id).
    success(function (data) {
        var userInfo = data.user[0];
        return userInfo;
    });
    return promise;
}) // other stuff comes after this

そして、あなたのコントローラーで、

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    userInfo.then(function(data){
        $scope.user = data;
    });
}

これにより、サービスを使用するたびに常にデータが提供されます同期、コントローラーをロードする前にデータをロードする必要はありません。

42
zs2020

userInfoサービスは、$httpによって返されたプロミスを返さなければなりません。その後、そのプロミスがコントローラーに注入され、プロミスが正常に解決されるとすぐにビューが更新されます。


userInfoが解決する前にビューをまったくレンダリングしたくない場合は、ルートにresolveプロパティを設定し、そこにサービスを注入する必要があります。

$routeProvider.when('/profile', {
    templateUrl: 'profile',
    controller: userProfile,
    resolve: {
         userInfoData: function ($q, userInfo) {
             return userInfo;
         }
    }
});

次に、userInfoDataサービスの代わりにuserInfoをコントローラーに挿入します。

17
Joseph Silber

$ resourceを使用してデータをサービスにロードし、そのデータをコントローラー$ scopeに取得する必要があるという同じ問題に直面しました。約束を直接返し、コントローラーでリゾルバーを使用したくありませんでした(@zsongが書いたように)が、一度サービスにすべての魔法をかけ、@ Josephとして約束を$ scopeに直接割り当てる機能を使用しましたシルバーが指摘しているので、ここに私がやったことがあります:

return function($scope){promise.then(function(data){$scope.user = data})};

そして、このようにコントローラーで使用しました:

userInfo($scope);

大した改善ではありませんが、コントローラーでより明確な構文が可能になりました。3年後でも役立つことを願っています。

0
PaulCo

$ http.get(url)を返すようなリソースオブジェクトを変数に割り当てることができます。

0