如何将工厂的更新应用于视图

How to apply updates from a factory to view

本文关键字:更新 应用于 视图 工厂      更新时间:2023-09-26

我正试图以asyn模式更改工厂中的引用,但在我的视图中没有看到更新。

查看

<div ng-repeat="Message in Current.Messages">{{Message.text}}</div>

控制器

angular.module('test').controller('testCtrl', function($scope, Service) {
  $scope.Current = Service.Current;
});

工厂

angular.module('test').factory('Service', function($rootScope) {
  var Service = function() {
    this.Current = { Messages: [] };
    this.Socket = io.connect(/* ... */);
  }
  Service.prototype.asyncEvent = function(Another) {
    this.Socket.on('event', function() {
      $rootScope.$apply(function() {
        this.Current = Another; // After this change, i would like my view to display the new object but nothing happens...
      }.bind(this));
    });
  };
  var service = new Service();
  return service;
});

当我尝试对.push()执行操作而不是更改引用时,它工作得很好,所以我知道这个问题并没有真正涉及异步。然而,我不知道如何使用工厂对我的视图的引用,以及如何随时更改我指向的对象。

您的问题是,通过执行this.Current = Another;,您正在用新的对象引用覆盖Current的引用,因此$scope.Current@$scope.Current = Service.Current持有的Current的引用具有旧的对象引用。所以它不会被反映出来。您可以引入多个对象层次结构来解决此问题,尤其是当您从服务中公开一个属性,并且您希望它被消费者用作活动属性时,您可以共享一个不变的引用。

在您的情况下,作为一个简单的修复程序,您可以使用this.Current.Messages = Another.Messages;而不是this.Current = Another;,这样您就不会在服务实例化期间更改serviceInstance.Current属性所持有的引用,而是只更改Messages Array。

尝试:-

angular.module('test').factory('Service', function($rootScope) {
  var Service = function() {
    this.Current = { Messages: [] };
    this.Socket = io.connect(/* ... */);
  }
  Service.prototype.asyncEvent = function(Another) {
    this.Socket.on('event', function() {
      $rootScope.$apply(function() {
        this.Current.Messages = Another.Messages; 
      }.bind(this));
    });
  };
  var service = new Service();
  return service;
});

但是,当您公开服务的属性时,您应该小心,它很容易被另一个使用者(控制器)意外或以其他方式覆盖,这可能会导致应用程序中的数据完整性问题。相反,公开方法,实现promise模式来传递数据,甚至可以使用pub/sub模式(甚至使用angular内置事件总线)让消费者知道事件的发生。