角度绑定到服务值不更新

时间:2015-05-06 01:22:06

标签: javascript angularjs

我无法获得绑定的服务值,以便在更改时进行更新。我尝试了很多这样做的方法,但没有一个有效,我做错了什么?从我所看到的一切来看,这似乎应该有用......

HTML:

<div class="drawer" ng-controller="DrawerController">
  {{activeCountry}}
</div>

控制器:

angular.module('worldboxApp')
    .controller('DrawerController', ['$scope', 'mapService', function($scope, mapService) {

        $scope.$watch(function() { return mapService.activeCountry }, function(newValue, oldValue) {
            $scope.activeCountry = mapService.activeCountry;
        });

    }]);

服务:

angular.module('worldboxApp').
    service('mapService', function(dbService, mapboxService, userService) {

    this.init = function() {
        this.activeCountry = {};
    }

    this.countryClick = function(e) {
        this.activeCountry = e.layer.feature;
    };

    this.init();
});

我设置了一个断点,以确保更改了mapService.activeCountry变量,但html中显示的所有变量都是{}

2 个答案:

答案 0 :(得分:1)

在某些情况下,$ watch不使用工厂对象。您可以使用事件进行更新。

 app.factory('userService',['$rootScope',function($rootScope){
  var user = {};
  return {

  getFirstname : function () {
    return user.firstname;
  },

  setFirstname : function (firstname) {
    user.firstname = firstname;
    $rootScope.$broadcast("updates");
  }

}
}]);
app.controller('MainCtrl',['userService','$scope','$rootScope', function(userService,$scope,$rootScope) {
  userService.setFirstname("bharat");
  $scope.name = userService.getFirstname();
  $rootScope.$on("updates",function(){
    $scope.name = userService.getFirstname();
  });
}]);

app.controller('one',['userService','$scope', function(userService,$scope) {
  $scope.updateName=function(){
    userService.setFirstname($scope.firstname);
  }
}]);

Here is the plunker

注意: - 在某些情况下,如果没有立即触发广播事件,您可以使用$ timeout。我已将其添加到plunker中,时间取决于您的需求。这对工厂和服务都有效。

答案 1 :(得分:1)

如果您在范围内使用对象及其属性,而不是直接使用字符串/数字/布尔值,那么您更有可能维护对正确范围的引用。

我认为指南是你通常希望有一个&#39;。&#39;绑定中的(点)(特别是ngModel) - 也就是说,{{data.something}}通常比{{something}}更好。如果更新对象上的属性,则会保留对父对象的引用,并且Angular可以看到更新的属性。

这对于您仅在控制器中设置和修改的道具通常并不重要,但对于从服务返回的值(并且可能由服务的多个消费者共享),我发现它有助于处理对象。

请参阅(这些关注与ngModel绑定的相关性):

&#13;
&#13;
angular.module('worldboxApp', []);

/* Controller */
angular.module('worldboxApp')
  .controller('DrawerController', ['$scope', 'mapService',
    function($scope, mapService) {
      //map to an object (by ref) rather than just a string (by val), otherwise it's easy to lose reference
      $scope.data = mapService.data;
      $scope.setCountry = setCountry; //see below

      function setCountry(country) {
        // could have just set $scope.setCountry = mapService.setCountry;
        // however we can wrap it here if we want to do something less generic
        // like getting data out of an event object, before passing it on to
        // the service.
        mapService.setCountry(country);
      }
    }
  ]);

/* Service */
angular.module('worldboxApp')
  .service('mapService', ['$log',
    function($log) {
      var self = this; //so that the functions can reference .data; 'this' within the functions would not reach the correct scope
      self.data = {
        activeCountry: null
      }; //we use an object since it can be returned by reference, and changing activeCountry's value will not break the link between it here and the controller using it

      _init();

      function _init() {
        self.data.activeCountry = '';
        $log.log('Init was called!');
      }


      this.setCountry = function _setCountry(country) {
        $log.log('setCountry was called: ' + country);
        self.data.activeCountry = country;
      }
    }
  ]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<div ng-app="worldboxApp">
  <div ng-controller="DrawerController">
    <button ng-click="setCountry('USA')">USA</button>
    <br />
    <button ng-click="setCountry('AUS')">AUS</button>
    <br />Active Country: {{data.activeCountry}}
  </div>
</div>
&#13;
&#13;
&#13;