2014-06-18 97 views
3

我试图从服务中加载数据并使用$ 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; 
}]); 

回答

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; 
     }]); 
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()只是将给定值包装在一个承诺中(模仿的响应在你的例子中为)。

+0

IIRC,结果在'.then'的HTTP是请求本身,和你想'result.data' –

+0

似乎在捣鼓做工精细没有'.data' –

+0

是的,但小提琴没有发出HTTP请求,是:) :)? –