更新angularjs服务对象而无需扩展/复制?

时间:2014-04-27 01:44:28

标签: javascript angularjs

我有2个服务,想要从第2个服务更新第1个服务中的变量。 在控制器中,我将范围变量设置为第一个服务的getter。

问题是,当服务变量发生变化时,附加到控制器的视图不会更新,除非我使用angular.extend / copy。看起来我应该能够在不必使用扩展/复制的情况下设置selectedBuilding。我做错了什么,或者你必须这样做?

控制器

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);
    ...
});

提前致谢!

2 个答案:

答案 0 :(得分:1)

我不相信你需要延长你的服务。您应该能够直接观看服务并回复更改:

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的更多信息:https://code.angularjs.org/1.2.16/docs/api/ng/type/$rootScope.Scope

答案 1 :(得分:1)

执行此代码时:

$scope.building = BuildingsService.getSelectedBuilding(); 

$scope.building 已复制内存中相同对象的引用,与您的服务selectedBuilding相同。当您将另一个对象分配给selectedBuilding时,$scope.building仍会引用旧对象。这就是视图未更新的原因,您必须使用angular.copy/extend

如果您需要为selectedBuilding分配新对象,可以尝试以下解决方案以避免此问题:

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以避免这种不必要的复杂性。