我需要通过API从我的数据库中获取一些数据,并在整个Angular应用程序中访问它。我知道服务适用于存储要从多个控制器访问的数据。但是,在下面的代码中,我每次只得到一个新的$ hhtp.get()来获取相同的数据。
服务:
.factory('Playlist', ['$http', function($http) {
var playlist = {};
playlist.getPlaylist = function() {
return $http.get('api/playlist.php')
.then(function (response) {
var data = response.data;
return data;
})
}
return playlist;
}])
控制器:
.controller('ScheduleCtrl', ['$http', 'Playlist', function($http, Playlist) {
var self = this;
Playlist.getPlaylist()
.success(function(playlist) {
self.playlist_id = playlist.id;
fetchItems();
})
var fetchScheduleItems = function() {
return $http.get('api/schedule.php/'+self.playlist_id).then(
function(response) {
if (response.data === "null") {
console.log("No items");
} else {
self.items = response.data;
}
}, function(errResponse) {
console.error('Error while fetching schedule');
});
};
}])
.controller('PlaylistItemCtrl', ['$http', 'Playlist', function($http, Playlist) {
var self = this;
Playlist.getPlaylist()
.success(function(playlist) {
self.playlist_id = playlist.id;
fetchItems();
})
var fetchPlaylistItems = function() {
return $http.get('api/schedule.php/'+self.playlist_id).then(
function(response) {
if (response.data === "null") {
console.log("No items");
} else {
self.items = response.data;
}
}, function(errResponse) {
console.error('Error while fetching schedule');
});
};
}])
有没有办法存储播放列表ID而无需从每个控制器ping“api / playlist.php”?
更新
这是基于Abhi答案的Plunkr:http://plnkr.co/edit/or9kc4MDC2x3GzG2dNeK?p=preview
正如您在控制台中看到的那样,它仍然会多次击中服务器。我试过以不同方式嵌套CachedData.save(),但它似乎不适用。
答案 0 :(得分:1)
我想说在本地存储您的数据(CachedData工厂 - 将其重命名为有意义的东西)并在您的getPlaylist方法中,在进行http调用之前,检查CachedData以查看您的数据是否存在,如果不存在,则执行http调用
代码将如下所示。我刚刚写了它,所以可能会有一些错误,但你得到了图片。
.factory('Playlist', ['$http', 'CachedData', function($http, CachedData) {
var playlist = {};
playlist.getPlaylist = function() {
if (CachedData.data) {
// return cached data as a resolved promise
} else
return $http.get('api/playlist.php')
.then(function (response) {
var data = response.data;
cachedData.save(data);
return data;
})
}
return playlist;
}])
// CachedData工厂
.factory('CachedData', function() {
var _data;
var cachedData = {
data: _data,
save: function(newData) {
_data = newData;
}
};
return cachedData;
})
编辑:还从控制器中删除fetchPlaylistItems并将其放入工厂。控制器只是viewmodel和view之间的粘合剂。将所有业务逻辑,http调用放入服务中。
编辑:我为你设置了一个插件here。我希望它有所帮助。
编辑:John,你看到两个服务器调用的原因是因为它们来自不同的控制器ManiCtrl1和MainCtrl2。到那时,调用MainCtrl2的getPlaylist方法,第一个http请求没有机会完成并保存数据。如果在调用服务方法之前向MainCtrl2添加超时,您将看到从缓存中检索数据。有关演示,请参阅this updated plunk。 这在具有多个视图的应用中会更有用,您可以在导航回视图时不想重新加载数据。 (理想情况下,根据您缓存的数据类型,您将有一些到期时间,之后您需要重新加载数据)。答案 1 :(得分:0)
调用该方法时可以进行一些预验证。
var playlist = {};
playlist.playlist = [];
playlist.getPlaylist = function () {
if (playlist.playlist.length <= 0) { //or some lodash _.isEmpty()
$http.get('api/playlist.php')
.then(function (response) {
playlist.playlist = response.data;
})
}
return playlist.playlist;
};
希望它有所帮助!