从 Angular 服务使用 $http 一次
Use $http once from Angular Service
我需要通过 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(),但它似乎并不适用。
您可以在调用该方法时进行一些预验证。
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;
};
希望对您有所帮助!
我会说将数据存储在本地(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;
}])
// 缓存数据工厂
.factory('CachedData', function() {
var _data;
var cachedData = {
data: _data,
save: function(newData) {
_data = newData;
}
};
return cachedData;
})
编辑:同时从控制器中删除 fetchPlaylistItems 并将其放入工厂。控制器只是您的视图模型和视图之间的粘合剂。将所有业务逻辑、http 调用放在一个服务中。
编辑:我已经为你设置了一个 plunk here。我希望它有所帮助。
编辑:约翰,您看到两个服务器调用的原因是因为它们来自不同的控制器 ManiCtrl1 和 MainCtrl2。这时,调用 MainCtrl2 的 getPlaylist 方法,第一个 http 请求没有机会完成并保存数据。如果在调用服务方法之前向 MainCtrl2 添加超时,您将看到数据是从缓存中检索的。有关演示,请参阅 this updated plunk。
这在具有多个视图的应用程序中会更有用,因为您不想在导航回视图时重新加载数据。 (理想情况下,根据您缓存的数据类型,您将有一些到期时间,之后您会想要重新加载您的数据)。
我需要通过 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(),但它似乎并不适用。
您可以在调用该方法时进行一些预验证。
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;
};
希望对您有所帮助!
我会说将数据存储在本地(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;
}])
// 缓存数据工厂
.factory('CachedData', function() {
var _data;
var cachedData = {
data: _data,
save: function(newData) {
_data = newData;
}
};
return cachedData;
})
编辑:同时从控制器中删除 fetchPlaylistItems 并将其放入工厂。控制器只是您的视图模型和视图之间的粘合剂。将所有业务逻辑、http 调用放在一个服务中。
编辑:我已经为你设置了一个 plunk here。我希望它有所帮助。
编辑:约翰,您看到两个服务器调用的原因是因为它们来自不同的控制器 ManiCtrl1 和 MainCtrl2。这时,调用 MainCtrl2 的 getPlaylist 方法,第一个 http 请求没有机会完成并保存数据。如果在调用服务方法之前向 MainCtrl2 添加超时,您将看到数据是从缓存中检索的。有关演示,请参阅 this updated plunk。 这在具有多个视图的应用程序中会更有用,因为您不想在导航回视图时重新加载数据。 (理想情况下,根据您缓存的数据类型,您将有一些到期时间,之后您会想要重新加载您的数据)。