2014-06-18 93 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請求,是:) :)? –