我正在使用Ionic和Angular构建一个简单的应用程序,并对我的工厂和全局变量有疑问。
我有一个JSON文件,其中包含应用程序中每个页面都需要使用的数据。应用中的每个页面都需要访问设备的lat / long。
目前,在每个页面的控制器中,我正在调用数据并等待承诺解决,然后再继续处理数据。在每个页面上,我也在控制器中为每个页面请求lat long。
这一切看起来都有点浪费,因为数据不会在页面之间发生变化,将lat设置为全局一次似乎是明智的(然后用watchPosition更新它,并在位置发生变化时使用回调更新被调用的数据)而不是必须获取位置并在每个页面$ scope上设置它。
数据是一个小的(~20)位置列表,每个位置都有一个lat长。我想计算当前lat long的每个位置的距离,随着位置的变化(来自watchPosition的回调)在数据中更新它。我的应用有2页。一个包含位置列表,另一个在Google地图上显示位置。两者都使用相同的数据。
我应该将它们存储在$ rootScope上还是被认为是不好的做法?我是以错误的方式思考这个问题吗?我应该继续当前的道路吗?
目前,我的控制器看起来像:
.....
.controller('HarboursCtrl', function($scope, Harbours) {
var harboursPromise = Harbours.all();
$scope.harbours = [];
$scope.position = 'Trying to find your location...'
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position){
$scope.$apply(function(){
$scope.position = position.coords.latitude+", "+position.coords.longitude;
})
})
} else {
$scope.position = "Sorry, we can't get your location";
}
harboursPromise.then(function(response){
console.log('response from controller', response);
$scope.harbours = response.harbours;
});
// $scope.harbours = Harbours.all();
$scope.remove = function(harbour) {
Harbours.remove(harbour);
};
$scope.getTimes=function(n){
return new Array(n);
};
})
.controller('MapCtrl', function($scope, Harbours) {
$scope.position = 'Trying to find your location...'
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position){
$scope.$apply(function(){
$scope.position = position.coords.latitude+", "+position.coords.longitude;
})
})
} else {
$scope.position = "Sorry, we can't get your location";
}
var harboursPromise = Harbours.all();
harboursPromise.then(function(response){
console.log('response from controller', response);
$scope.map = { center: { latitude: 51, longitude: 0 }, zoom: 10 };
$scope.harbours = [];
$scope.harbours = response.harbours;
console.log($scope.map.harbours);
});
});
.....
我的服务如下:
angular.module('starter.services', [])
.factory('Harbours', function($http, $q) {
var harbours = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: '../data/harbourData.json'
}).success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function(data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
}
return {
all: harbours,
get: function(chatId) {
for (var i = 0; i < harbours.length; i++) {
if (harbours[i].id === parseInt(chatId)) {
return harbours[i];
}
}
return null;
}
};
});
答案 0 :(得分:2)
您的数据是静态的吗?如果是这样,最好写一个常量而不是使用$ http / $ q。
angular.module('myModule')
.constant('locations', {
firstItem: {
lat: 'someValue',
long: 'someValue'
},
etc: {}
});
所以你不必每次都打电话。如果数据是动态的,您可以随时在工厂中缓存值,如下所示:
.factory('myFactory', ['$http', '$q', function($http, $q) {
var harbors = /* resolved object with data */;
return {
all: harbors,
get: function(name) { return harbors[name]; }
};
});
tldr;工厂是单件,所以缓存在其中的任何数据应该可以在应用程序的任何地方使用,而无需调用$ http服务。
*编辑*
我可能采用的方法是创建一个单独的工厂来缓存我需要重用的任何数据,并编写一个帮助缓存它的API工厂。所以,
.factory('appData', [function() {
var cache = {};
return {
set: function(location, payload) {
cache[location] = payload;
},
get: function(location) {
return cache[location];
},
reset: function() {
cache = {};
}
};
}])
.factory('callAPI', ['$http', '$q', 'appData', function($http, $q, appData) {
return {
endpoint: function(url, payload, method, cache) {
var deferred = $q.defer();
$http({
method: method,
url: url
}).success(function(data, status, headers, config) {
deferred.resolve(data);
}).success(function(data, status, headers, config) {
deferred.reject(status);
});
/** cache must be a string */
appData.set(cache, deferred.promise);
return deferred.promise;
}
}
}])
这也保持了应用程序中关注点的分离。