指令不会更新服务模型更改

时间:2014-10-14 14:54:53

标签: angularjs angularjs-directive angularjs-service

我有一个包含我的应用程序模型的服务:

angular.module('adminClient').factory('myApi', function () {
    var model = {};
    model.myObject = {
        label: 'New York City'
    };

    return {
        model: function () {
            return model;
        }
    };
});

部分/控制器可以访问模型并可以设置新的myObject:

angular.module('adminClient').controller('MySelectNetworkCtrl', function ($scope, myApi) {

    $scope.myObject = myApi.model().myObject;

});

除此之外,我还有一个指令,它应该显示myObject中包含的标签:

angular.module('nav').directive('myTopBar', function(myApi) {
    return {
        restrict: 'E',
        replace: true,
        scope: {},
        templateUrl: 'nav/directive/my-top-bar/my-top-bar.html',
        link: function(scope, element, attrs, fn) {
            scope.myObject = myApi.model().myObject;
        }
    };
});

这是HTML:

<div id="my-top-bar">
    <span ng-bind="myObject"></span>
</div>

当我运行应用程序时,标签显示正常(纽约市),但是一旦控制器更改了myObject,指令中的标签就保持不变。我也可以在Chrome Angular范围检查器中看到这一点。

任何想法如何使指令显示当前值,即使在控制器更改后也是如此?

2 个答案:

答案 0 :(得分:1)

这完全取决于控制器如何更新模型对象。既然你的代码

scope.myObject = myApi.model().myObject;

获取此特定模型对象,只要模型对象myObject属性发生更改,它就可以正常工作。

但如果控制器

myApi.model().myObject= {}; //or any new object

现在服务返回的模型有不同的myObject,而指令1则不同。因此,更改不起作用。

而是在指令中执行:

scope.myObject = myApi.model(); // bind to model

并相应地更新指令模板中的绑定。看看它是否有效

答案 1 :(得分:0)

选中此plunkr

如果您想修改控制器内的myObject,并希望此更改反映在my-top-bar指令中,然后从myApi服务更新指令的范围,那么您应该这样做。

更新控制器中的myObject,然后通过setter方法在服务中更新它。

// Doing this will update your scope.myObject but 
// will not change the moObject in your service
$scope.myObject = {
  label: 'updated label'
};

// This will update your service, and anyone making a myApi.myApi.model() after this will get an updated myObject
myApi.setModel($scope.myObject);
// Notify directive of the change
$scope.$broadcast('updateDirective');

在工厂里:

angular.module('plunker').factory('myApi', function() {
  var model = {};
  model.myObject = {
    label: 'New York City'
  };

  return {
    model: function() {
      return model;
    },
    setModel: function(newModel) {
      model.myObject = newModel;
    }
  };
});

最后,指令:

angular.module('plunker').directive('myTopBar', function(myApi) {
  return {
    restrict: 'E',
    replace: true,
    scope: {},
    templateUrl: 'top-bar.html',
    link: function(scope, element, attrs, fn) {
      console.log('in directive link', myApi.model().myObject);
      scope.myObject = myApi.model().myObject;
    },
    controller: function($scope) {
      $scope.$on('updateDirective', function() {
        console.log('updating the scope of directive so that ng-bind works');
        $scope.$apply(function() {
          $scope.myObject = myApi.model().myObject;
          console.log($scope.myObject);
        });
      });
    }
  };
});