我想创建一个加载JSON文件的服务,并提供一些处理结果的方法。
Blog.service('ArticleService', ['$http', function ($http) {
this.loadArticles = function() {
return $http.get('data/articles.json');
};
this.getArticles = function () {
// return the json
};
this.getArticle = function (id) {
// work with the json
};
}]);
控制器:
Blog.controller('BlogController', function ($scope, ArticleService) {
console.log(ArticleService.getArticles());
console.log(ArticleService.getArticle(1));
});
我想缓存请求的结果,然后在我的方法getArticles
和getArticle
中使用此结果。
答案 0 :(得分:1)
根据您的评论,如果您只想做一个请求,那么我建议您在服务中的变量中保存$ http承诺,并在getArticles中返回该变量。
Blog.service('ArticleService', ['$http', function ($http) {
this.loadArticles = function() {
return $http.get('data/articles.json');
};
var articles;
this.getArticles = function () {
if (!articles) {
articles = this.loadArticles();
}
return articles;
};
this.getArticle = function (id) {
// work with the json
};
}]);
或者更好的是,在init上加载articles
变量:
Blog.service('ArticleService', ['$http' '$q', function ($http, $q) {
var articles = (function() {
return $http.get('data/articles.json');
})();
this.getArticles = function () {
return articles;
};
this.getArticle = function (id) {
// Return a promise that will be resolved with the correct article.
var deferred = $q.defer();
articles.then(function (arts) {
arts.forEach(function (art) {
if (art.id === id) {
deferred.resolve(art);
}
});
});
return deferred.promise;
};
}]);
Angular曾用于解开承诺,但这被弃用,因为它被证明是麻烦而且非常“神奇”(导致误解)。见https://github.com/angular/angular.js/issues/5153
答案 1 :(得分:1)
或者,您可以使用$http
的缓存属性:
Blog.service('ArticleService', ['$http', function ($http) {
this.getArticles = function() {
return $http.get('data/articles.json', {cache: 'myCache'});
};
this.getArticle = function (id) {
return $http.get('data/articles.json', {cache: 'myCache'}).then(function(response) {
// Parse the response, return the article in question.
});
};
}]);
答案 2 :(得分:0)
Blog.service('ArticleService', ['$http', '$q', function ($http, $q)
{
var self = this;
this.loadArticles = function ()
{
var deffered = $q.defer();
$http.get("data/articles.json").then(
function (result)
{
deffered.resolve(result);
},
function ()
{
deffered.reject()
}
);
return deffered.promise;
};
this.getArticles = function ()
{
return self.loadArticles;
};
this.getArticle = function (id)
{
// some stuff to retrieve the object
};
}]);
然后在您的控制器中
Blog.controller('BlogController', function ($scope, ArticleService)
{
ArticleService.getArticles().then(function (data)
{
console.log(data);
}, then(function ()
{
alert("error")
})
);
});
});
答案 3 :(得分:0)
如果您希望缓存在会话期间保持不变,请参阅user3904的答案。
如果缓存可以随页面消亡,那么您可以考虑以下方法:
Blog.service('ArticleService', ['$http', '$q', function ($http, $q) {
var articles = {};
var loadArticles = function () {
articles.multi = $http.get("data/articles.json").done(function(a) {
articles.multi = a;
});
return articles.multi;
};
var loadArticle = function (id) {
articles[id] = $http.get("data/articles.json/" + id).done(function(a) {
articles[id] = a;
});
return articles[id];
};
this.getArticles = function () {
return articles.multi ? $q.when(articles.multi) : loadArticles();
};
this.getArticle = function(id) {
id = '' + id;
return articles[id] ? $q.when(articles[id]) : loadArticle(id);
};
}]);
缓存是js普通对象articles
。
这两个load...()
函数是私有的 - 假设它们只能通过相应的get...()
函数来调用,这似乎是合理的。 (这对整体解决方案并不特别重要)。
在第一次调用时,两个loadArticles()
缓存一个promise,当promise数据到达时,promise将被promise承诺的数据覆盖。承诺暂时缓存有一个原因 - 如果在从服务器返回数据之前发出第二个请求。 $q.when(...)
中的this.getArticles()
可确保loadArticles()
返回包含承诺的数据,无论当前是什么缓存 - 承诺或数据。
this.getArticle()
与this.getArticles()
的工作方式类似,但接受(并传递)了一个ID。
此策略旨在提高存储效率。通过长期缓存数据,避免了promise包装器的(小)开销。如果用户可能在每个会话中请求许多单独的文章,则可能会出现问题。
以高效缓存高效物品的成本为代价购买存储效率。 $q.when(...)
需要一些额外的时钟周期才能完成。
使代码适应其他方式应该非常简单 - 即以存储效率为代价优化交付 - 即长期存储承诺并避免需要$q.when(...)
。
这两种方法都适用,对于大多数应用来说,它采用的是相当优秀的学术方法。