AngularJS使用$ q promises更新服务/模型更新视图

时间:2014-06-18 22:33:17

标签: angularjs promise angular-promise

我尝试从服务加载数据并使用$ q更新视图,但它无法正常工作。如果我将http调用放在控制器中,它可以工作,但我更喜欢它是服务的一部分。

有任何帮助吗?另外,有没有更好的方法来做这个而不是承诺?

下面的演示和代码。

---------- Fiddle Demo Link ----------

查看

<div ng-init="getData()">
  <div ng-repeat="item in list">{{item.name}}</div>
</div>

控制器

.controller('ctrl', ['$scope', 'dataservice', '$q', function ($scope, dataservice, $q) {

  $scope.list = dataservice.datalist;

  var loadData = function () {
    dataservice.fakeHttpGetData();
  };

  var setDataToScope = function () {
    $scope.list = dataservice.datalist;
  };

  $scope.getData = function () {
    var defer = $q.defer();
    defer.promise.then(setDataToScope());
    defer.resolve(loadData());
  };

}])

服务

.factory('dataservice', ['$timeout', function ($timeout) {

  // view displays this list at load 
  this.datalist = [{'name': 'alpha'}, {'name': 'bravo'}];

  this.fakeHttpGetData = function () {
    $timeout(function () {

      // view should display this list after 2 seconds
      this.datalist = [{'name': 'charlie'}, {'name': 'delta'}, {'name': 'echo'}];
    },
    2000);
  };

  return this;
}]);

2 个答案:

答案 0 :(得分:1)

首先,不要以这种方式使用ng-init。根据文档:

  

ngInit的唯一合适用途是对特殊属性进行别名处理   ngRepeat的内容,如下面的演示所示。除了这种情况,你应该   使用控制器而不是ngInit来初始化作用域上的值。

其次,在这种情况下,承诺是完美的选择,但您不需要触摸$q,因为$http来电会为您回复承诺。

要正确执行此操作,只需返回服务中的$http结果:

this.getDataFromService = function() {
    return $http(/* http call info */);
};

然后,在你的控制器里面:

dataservice.getDataFromService().then(function(result){
    $scope.list = result.data;
});    

此处还有更新的小提琴:http://jsfiddle.net/RgwLR/

请记住,$q.when()只是将给定值包装在一个承诺中(模仿示例中$http的响应)。

答案 1 :(得分:1)

不需要ngInit或$ q。这就是你应该怎么做的。

您也不应将dataservice.list公开给控制器。这应该是dataservice的私有,它将包含大部分逻辑,以确定是将控制器发送到现有列表还是更新列表然后发送它。

angular.module('app', [])

        .controller('ctrl', ['$scope', 'dataservice', function ($scope, dataservice) {

            loadData();

            function loadData() {
                dataservice.fakeHttpGetData().then(function (result) {
                    $scope.list = result;
                });
            }
        }])

        .factory('dataservice', ['$timeout', function ($timeout) {

            var datalist = [
                {
                    'name': 'alpha'
                },
                {
                    'name': 'bravo'
                }
            ];

            this.fakeHttpGetData = function () {

                return $timeout(function () {

                            // Logic here to determine what the list should be (what combination of new data and the existing list).

                            datalist =  [
                                {
                                    'name': 'charlie'
                                },
                                {
                                    'name': 'delta'
                                },
                                {
                                    'name': 'echo'
                                }
                            ];

                            return datalist;
                        },
                        2000);
            };

            return this;
        }]);