Angular 使用 $http 刷新来自服务的数据时视图未更新

Angular view not updating when refreshing data coming from service with $http

这个问题可能被问了一万次了,但我仍然找不到合适的解决方案。

我只有控制器从服务获取数据的经典示例,它又使用 $http 从 API(或 JSON 文件)异步获取一些数据.因为控制器中的数据是对服务中对象的引用,所以我希望数据在服务完成其工作时发生变化,因此我希望视图能够更新。正如您在下面的代码片段中看到的那样,视图保留了初始值。

因此,我的两个问题:

  1. 这个模式好吗?想象一下,控制器不止一个,并且在某个时候需要重新获取数据(并因此在任何控制器中更新)
  2. 为什么视图没有更新?

请记住,我不想使用 $scope(如果可能)、$rootSscope 或 $watch。

var app = angular.module('myApp', [])
.service('Service', ['$http', service])
.controller('Controller', ['Service', controller]);


function controller(Service){
    var c = this;
    c.items = [
      {'title': 'Default title1'},
      {'title': 'Default title2'}
    ];
    c.items = Service.data;
}

function service($http, $scope){
    var data = [
      {'title': 'olddatatitle'}
    ];
    $http({
      method: 'GET',
      url: 'https://jsonplaceholder.typicode.com/posts?userId=1',
      cache: true
    }).then(function(response){
      data = response.data;
    });
    return {
      data: data
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" >
  <ul ng-controller="Controller as c">
    <li ng-repeat="item in c.items">
      {{item.title}}
    </li>
  </ul>
</div>

c.items = Service.data;

上面的行从来没有 api 调用的响应,因为当你的 api returns 响应时,JS 已经移动到下一个语句.. .你需要提供一个callback

您的问题是一个异步问题...您不希望在您的服务中从 $http 获取数据并期望它在您的控制器准备就绪时准备就绪。不要尝试 return 数据,而是 return 数据的承诺:

function service($http, $scope){
    //var data = [
    //  {'title': 'olddatatitle'}
    //];

    return {
      getData: function() {
        return $http({    // calls to $http return a promise object
          method: 'GET',
          url: 'https://jsonplaceholder.typicode.com/posts?userId=1',
          cache: true
        });
    }
}

这样您的控制器就会准确知道数据何时可以使用:

function controller(Service){
    var c = this;
    //c.items = [
    //  {'title': 'Default title1'},
    //  {'title': 'Default title2'}
    //];
    Service.getData().then(function(response) {    // the promise object allows you to assign data only when it's ready
      c.items = response.data
    });
}

你不明白promise是什么。您实际上需要来自服务的 return 承诺,而不是数据。在服务定义时,没有数据。它只会在您完成服务呼叫后才出现。因此,与 promise 一起工作的部分需要在调用使用服务的代码中,而不是在服务定义中:

var app = angular.module('myApp', [])
.service('Service', ['$http', service])
.controller('Controller', ['Service', controller]);


function controller(Service){
    var c = this;
    c.items = [
      {'title': 'Default title1'},
      {'title': 'Default title2'}
    ];
    Service.get().then(function(payload) {
     console.log(payload);
      c.items = payload.data;
    });
}

function service($http, $scope){
    var data = [
      {'title': 'olddatatitle'}
    ];
    var get = function() {
     return $http({
      method: 'GET',
      url: 'https://jsonplaceholder.typicode.com/posts?userId=1',
      cache: true
    })};
    return {
      get: get
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" >
  <ul ng-controller="Controller as c">
    <li ng-repeat="item in c.items">
      {{item.title}}
    </li>
  </ul>
</div>