Javascript 是否可以在不扩展/复制的情况下更新angular.js服务对象?
我有2个服务,希望从第2个服务更新第1个服务中的变量。 在控制器中,我将范围变量设置为第一个服务的getter 问题是,附加到控制器的视图不会在服务变量更改时更新,除非我使用angular.extend/copy。似乎我应该可以在下面设置Javascript 是否可以在不扩展/复制的情况下更新angular.js服务对象?,javascript,angularjs,Javascript,Angularjs,我有2个服务,希望从第2个服务更新第1个服务中的变量。 在控制器中,我将范围变量设置为第一个服务的getter 问题是,附加到控制器的视图不会在服务变量更改时更新,除非我使用angular.extend/copy。似乎我应该可以在下面设置selectedBuilding,而不必使用extend/copy。是我做错了什么,还是你必须这样做 控制器 app.controller('SelectedBuildingCtrl', function($scope, BuildingsService) {
selectedBuilding
,而不必使用extend/copy。是我做错了什么,还是你必须这样做
控制器
app.controller('SelectedBuildingCtrl', function($scope, BuildingsService) {
$scope.building = BuildingsService.getSelectedBuilding();
});
服务1
app.factory('BuildingsService', function() {
var buildingsList = [];
var selectedBuilding = {};
// buildingsList populated up here
...
var setSelectedBuilding = function(buildingId) {
angular.extend(selectedBuilding, _.find(
buildingsList, {'building_id': buildingId})
);
};
var getSelectedBuilding = function() {
return selectedBuilding;
};
...
return {
setSelectedBuilding: setSelectedBuilding,
getSelectedBuilding: getSelectedBuilding
}
});
服务2
app.factory('AnotherService', function(BuildingsService) {
...
// something happens, gives me a building id
BuildingsService.setSelectedBuilding(building_id);
...
});
提前谢谢 我认为您的服务不需要延长。您应该能够直接观看服务并响应更改:
app.controller('SelectedBuildingCtrl', function($scope, BuildingsService) {
// first function is evaluated on every $digest cycle
$scope.$watch(function(scope){
return BuildingsService.getSelectedBuilding();
// second function is a callback that provides the changes
}, function(newVal, oldVal, scope) {
scope.building = newVal;
}
});
有关$watch的详细信息:执行此代码时:
$scope.building = BuildingsService.getSelectedBuilding();
$scope.building
是复制的内存中与服务的所选building
相同对象的引用。当您将另一个对象指定给所选建筑
时,$scope.building
仍然引用旧对象。这就是视图未更新的原因,您必须使用angular.copy/extend
如果需要将新对象指定给所选建筑,可以尝试以下解决方案以避免此问题:
app.factory('BuildingsService', function() {
var buildingsList = [];
var building = { //create another object to **hang** the reference
selectedBuilding : {}
}
// buildingsList populated up here
...
var setSelectedBuilding = function(buildingId) {
//just assign a new object to building.selectedBuilding
};
var getSelectedBuilding = function() {
return building; //return the building instead of selectedBuilding
};
...
return {
setSelectedBuilding: setSelectedBuilding,
getSelectedBuilding: getSelectedBuilding
}
});
使用此解决方案,您必须更新视图以替换$scope.building
到$scope.building.selectedBuilding
的绑定
在我看来,我将坚持使用
angular.copy/extend
,以避免这种不必要的复杂性。不确定这是否对您更有效,但您可能希望了解angular事件。请参阅:。特别是$broadcast
、$emit
和$on
可能会引起您的兴趣。例如,当选定的建筑发生变化时,您可以广播一个事件(例如,selectedBuildingChanged
),该事件可能在控制器中$on
'd做出相应的反应。@brianmarco I一开始使用$broadcast
和$on
,但它比getter/setters更难测试。团队中的其他人只是在学习angular,所以我会尽可能的把事情弄清楚。啊,好的。你有没有机会和测试人员分享你的困难?我们在应用程序中使用事件处理某些事情,但老实说,我们可能不会对它们进行深入的测试。当然,当对$broadcast
事件进行单元测试时,我最终不得不使用jasmine的spyOn($rootScope,'broadcast')。和callthrough()
。但是由于$rootScope调用了来自第三方插件的其他事件,因此测试涉及1。很多嘲弄或嘲笑。在整个测试过程中调用$rootScope.$apply()
非常聪明,以确保我可以丢弃我不关心的事件并捕获我所做的事件。我觉得这太复杂了,于是想办法少用$broadcast
。啊,我明白了。非常感谢分享。