2016-07-14 72 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

没有后顾之忧,角度可以有点反复无常的野兽!奇怪的是,在我使用它的这几年中,我很少使用服务而不是工厂,但很好,你正在尝试新事物! –