在Angular中有一件我无法理解的事情 - 如何更好地将API数据与本地数据同步。
我的结构对象非常大,我只举几个例子。
我有4个api链接。
api_links: {
allCars: '/cars/',
cabrio: '/cars/cabrio',
sedan: '/cars/sedan',
mercedes: 'cars/sedan/mercedes'
}
这是我本地保存数据的本地对象
$rootScope.apiData = {
cars{
cabrio:{},
sedan: {}
}
}
在我的单页应用中,我希望减少请求数。 因此,在常见页面上,我收到所有汽车并将数据放入$ rootScope.apiData
当我进入轿车页面时,我会检查$ rootScope.apiData.cars.sedan中是否有任何数据。如果它存在,我不发送请求。
但如果我从轿车页面开始,我只收到轿车。然后,当我进入公共页面 - 如何检查我是否需要加载更多类别。
这是一个快速抽象的例子。但我试图为此找到任何好的解决方案或插件,但不能。
请帮助我!
更新:
这是我的工厂:
var api = angular.module('app.api', []);
api.factory('GetData', ['$http', '$q', '$rootScope', '$location'
function($http, $q, $rootScope, $location) {
var apiUrl = '/api/js/';
var apiMixes = {
dashBoard: 'api/dashboard',
accounts: 'api/accounts',
top: 'top',
logout: 'client/logout',
...
}
var methods = {};
methods.getApi = function(u, params) {
var url = apiMixes[u] + '?' + $.param( params );
var deferred = $q.defer();
// Here I need to check if I have cached data
cachedData(data) = ___TODO___;
if( cachedData(data) ){
deferred.resolve(cachedData(data));
// Turn watching on
$rootScope.$emit("receivedApiUpdate", cachedData(data));
return deferred.promise;
}
// If no - get gata from server and put to cache
$http.get(url, {cache: true}).success(function (res, status, headers, config) {
if(res && res.data){
// Turn watching on
$rootScope.$emit("receivedApiUpdate", res.data);
//LocalData.put(res.data);
deferred.resolve(res.data);
}else{
deferred.reject(status);
}
}).error(function (res, status, headers, config) {
(status==401) && $location.path('login/lock');
deferred.reject(status);
});
return deferred.promise;
};
methods.sendData = function(u, data, o) {
data = data || {};
o = o || {};
var deferred = $q.defer();
var url = '/api/js/'+ apiMixes[u];
$http.post(url, JSON.stringify(data)).success(function(res, status) {
if(res.success && res.data){
// Here I need to update my cache with some new value
o.localUpdate && ___PUT_TO_CACHE_TODO___;
deferred.resolve(res.data);
}
});
return deferred.promise;
};
return methods;
}]);
这是我的控制器
app.controller('MyAccountsCtrl', ["$rootScope", "$scope",
function ($rootScope, $scope) {
// Watcher for api updates
$rootScope.$on('receivedApiUpdate',function(event, response){
if(!response || !response.accounts) return;
renderData(response.accounts);
});
function renderData(accounts){
// This renders to template
$scope.accountList = accounts;
}
}]);
这是mainCtrl,whick做出常见请求,之后我需要更新几个模板中的数据。
app.controller('AppCtrl', ['$rootScope', '$scope', 'GetData',
function ($rootScope, $scope, GetData) {
// Here I fire different request for each page, I keep requests in router.
GetData.getApi( 'accounts' ).then(function(data){
// Show content when page is loaded
$('.main-content').removeClass('hidden');
},function(res){
log('GET DATA FAIL', res);
});
}]);
答案 0 :(得分:1)
您需要为此创建服务/工厂,而不是使用$ rootScope。此外,除非您需要不断更新数据,否则您可以使用$ http调用中的cache: true
选项。
angular
.module('app')
.factory('carFactory', carFactory);
function carFactory() {
var factory = {
getData: getData
}
return factory;
function getData(callback) {
$http({
method: 'GET',
url: '/cars',
cache: true
}).success(callback);
}
}
然后在您的控制器/指令内部注入carFactory
并在需要数据时使用carFactory.getData(function(cars) { ... })
。如果数据不存在,它将为$ http调用它,然后执行回调函数。如果它确实存在,它将直接将数据返回给回调,而不需要$ http调用。