2016-07-14 35 views
1

SIR間,我有AngularJS一個問題...AngularJS:加載延遲JSON和使用它的多個控制器

我試圖加載承諾一個JSON文件,並有兩個控制器不同的使用它..我嘗試了很多不同的技術,但我不明白......你能幫我嗎?

//SERVICE 
app.service('AllPosts', function($http, $q){ 
    var deferred = $q.defer(); 
    $http.get('posts.json').then(function(data){ 
     deferred.resolve(data); 
    }); 
    this.getPosts = function(){ 
     return deferred.promise; 
    }; 
    this.getPost = function(id){ 
     var post={}; 
     angular.forEach(deferred.promise, function(value) { 
      if(value.id == id){ 
       post=value; 
      } 
     }); 
     return post; 
    }; 
}); 

我創建一個服務調用JSON並以同樣的方式,我宣佈我的功能我控制器...

app.controller('AllCtrl', function($scope, AllPosts){ 
    AllPosts.getPosts().then(function(posts){ 
     $scope.posts = posts.data; 
    }); 
}); 

在我的第一個控制器我調用函數getPosts獲得所有從我的JSON的職位...

app.controller('PostCtrl', function($scope, AllPosts, $routeParams) { 
    AllPosts.getPost($routeParams.id).then(function(the_post){ 
     $scope.comments = post.comments; 
     $scope.title = post.name; 
     $scope.the_content = post.content; 
    }); 
}); 

在第二個控制器,我只想要的職位之一,所以我調用函數的getPost ...

但我不知道該怎麼辦,在第一種情況下,它適用於所有帖子,但在第二種情況下,不會......我是Angular的新手,如果您有其他方法,它會是太棒了! 非常感謝!

回答

0

爲了讓您getPost()工作,你有事情,現在需要做的方式:

this.getPost = function(id) { 
    // return same promise 
    return deferred.promise.then(function(posts) { 
    // but return only one post 
    var post = {}; 
    angular.forEach(posts, function(value) { 
     if (value.id == id) { 
     post = value; 
     } 
    }); 
    return post; 

    }) 

}; 

然而$http自己返回的承諾,這樣你就不會在所有

app.service('AllPosts', function($http) { 

    var postsPromise = $http.get('posts.json').then(function(response) { 
    return response.data 
    }); 
    this.getPosts = function() { 
    return postsPromise; 
    }; 
    this.getPost = function(id) { 
    // return same promise 
    return postsPromise.then(function(posts) { 
     // but return only one post 
     var post = {}; 
     angular.forEach(posts, function(value) { 
     if (value.id == id) { 
      post = value; 
     } 
     }); 
     return post; 

    }) 

    }; 
}); 
+0

嗯,好的謝謝,我現在就試試吧! :) –

+0

感謝您的回答,我不能讓它工作,不知道爲什麼,但我會看得更近...謝謝;)哦,順便說一句,carefull與postsPromise和postPromise :) –

+0

控制檯中的任何錯誤?需要隔離什麼是或不在工作 – charlietfl

0

你」需要$基本上幾乎在那裏,你只是有一些與您的代碼放置/訂購問題。爲了能夠在每個控制器中撥打AllPosts.getPosts(),您需要對服務進行一些調整。

首先,您應該將您的服務更改爲工廠。工廠是singletons,而服務具有調用每個調用/注入的實例,就像使用new運算符的類/對象一樣。 這只是爲了讓您可以在所有控制器中擁有一組一致的值,而不會浪費資源爲每個控制器實例化新服務。他們都會分享同一個。其次,你只需要對promise/deferrer模式做一些改變。請看下圖:

// Factory - REMEMBER TO INCLUDE LODASH 
app.factory('AllPosts', function($http, $q){ 
    var self = {}; 
    // create a private posts array to store the cached values 
    // The reason for making it private is to prevent you from 
    // directly accessing it rather than using the getter function, 
    // potentially giving you the wrong/old values; 
    var posts = []; 
    var expiry = null; 
    self.getPosts = function(){ 
     var deferred = $q.defer(); 
     var currentTimeStamp = new Date.getTime(); 
     // if we have a cached value, that hasn't expired, 
     //get that instead of making another http call 
     if(self.posts.length > 0 && currentTimeStamp !== null && 
     currentTimeStamp < expiry) { 
     deferred.resolve(self.posts); 
     return deferred.promise; 
     } 
     $http.get('posts.json').then(function(data){ 
     // cache the values to remove the 
     // need for multiple $http calls 
     expiry = new Date().getTime() + (1000 * 60 * 5) // expire in 5 minutes 
     posts = data; 
     deferred.resolve(data); 
     }); 
     return deferred.promise; 
    }; 
    self.getPost = function(id){ 
     // Use lodash to simplify your life :) 
     return _.find(posts, {id: id}); 
    } 
    return self; 
}); 

我會強烈建議像lodashunderscore庫來幫助你,如果你打算做了很多的集合/數組操作和/或迭代。

+0

哇,感謝您的更改......我稍後再試。我正在學習Angular,所以我試圖不添加任何其他庫,但我會仔細看看Lodash ......謝謝。而事情是,我已經做了一個工廠,我想學習服務,但我明白啊啊 –

+0

沒有後顧之憂,角度可以有點反覆無常的野獸!奇怪的是,在我使用它的這幾年中,我很少使用服務而不是工廠,但很好,你正在嘗試新事物! –