当其他服务更新服务的绑定属性时,为什么不更新$ scope?

时间:2016-02-08 22:02:53

标签: javascript angularjs

我有一个处理数据的服务,一个用于逻辑。

T

数据服务具有app.service('DataService', function() { this.stuff = [false]; this.setStuff = function(s){ this.stuff = angular.copy(s); } }); 功能和set属性。

data

我正在将数据服务的属性分配给控制器以绑定到DOM。

app.service('LogicService', function(DataService, $http) {
  DataService.setStuff(["apple", "banana"]);
  $http.get("./data.json").then(function(res){
    DataService.setStuff(res.data.stuff);
  });

});

如果我在实例化逻辑服务时“播种”数据服务,然后在app.controller('MainCtrl', function($scope, DataService, LogicService ) { $scope.message = "Hello, World!"; $scope.stuff = DataService.stuff; //This is the only way I could get it to work, but isn't this JANKY? //$scope.$watch( // function(){ // return DataService.stuff // }, // function(n,o){ // $scope.stuff = n; // }) }) 调用之后更新它,则DOM会反映“种子”或初始值,但不会更新。

在理解摘要循环时,我是否缺少一些基本的东西?

如果我在我的控制器中添加$ watch功能,一切都很好,但这看起来很难吃。

// // FIXED

@ scott-schwalbe使用$http的方法效果很好,保留了原始结构,并且是一行。

Object.asign()

Working Plunker

(抱歉为标题)

3 个答案:

答案 0 :(得分:1)

如果您的数据属性是一个对象并绑定到范围,那么只要您不取消引用它(例如data = x),只要对象发生更改,范围就会更新。你是否在$ http电话上重新分配数据对象?

使用Object.assign

保留引用的当前代码的替代方法
app.service('DataService', function() {
  this.stuff = [false];
  this.setStuff = function(s){
    Object.assign(this.stuff, s);
  }
});

答案 1 :(得分:0)

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, DataService) {
  $scope.message = "Hello, World!";

   //Get stuff data from your service, this way you stuff lives in your service  
   //And can be accessed everywhere in your app.   
   //It also makes your controller thin. Which is the top priority
   $scope.stuff = DataService.getStuff();
   //Or async
   DataService.getStuffAsync()
      .then(function(val){
       $scope.asycStuff = val;
   });

    this.clickFromAButton = function(){
      DataService.setStuff(["apple", "banana"]);
    };
});


app.service('DataService', function() {
  this.stuff = [false];
  this.asyncStuff;

  this.setStuff = function(s){
    this.stuff = angular.copy(s);
  };

  this.getStuff = function(){
      return this.stuff;
  };

  this.getStuffAsync = function(){
     //If i already fetched the data from $http, get it from the service.  
     return this.asyncStuff || $http.get("./data.json").then(function(res){
        //When i fetch it for the first time I set the data in my service
        this.asyncStuff  = res.data;
        //and I return the data
        return res.data;
     });
  };

});

这是一个很好的“模式”;)

答案 2 :(得分:0)

而不是放置"东西"在范围上。将DataService对象放在范围内。

app.controller('MainCtrl', function($scope, DataService, LogicService  ) {
  $scope.message = "Hello, World!";
  $scope.DataService = DataService;
  //$scope.stuff = DataService.stuff;

HTML

  <body ng-controller="MainCtrl">
    {{DataService.stuff}}
  </body>

$interpolate服务会自动在$watch上放置DataService.stuff。因此,无需在控制器内执行此操作。

DEMO on PLNKR