使用$http刷新来自服务的数据时,角度视图不更新

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

本文关键字:视图 更新 数据 http 刷新 服务 使用      更新时间:2023-09-26

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

我只有一个控制器从服务获取数据的经典示例,该服务反过来使用$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>

您的问题是异步的。。。你不想从服务中的$http获取数据,并期望它在控制器准备好时准备好。不要试图返回数据,而是返回数据承诺:

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
    });
}
c.items = Service.data;

上面的行从来没有api调用的响应,因为当你的api返回响应时,JS已经转到下一个语句了。。。您需要提供callback

您不明白什么是promise。您实际上需要从Service返回promise,而不是数据。与服务定义时一样,没有任何数据。只有在您完成服务呼叫后,它才会出现在那里。因此,使用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>