2014-10-31 63 views
0

我想要做的最簡單的事情,AngularJS顯然使難以置信的困難。這裏更多問題與「易於學習」的angularjs框架

此代碼:

.factory('ItemService', [function() { 
var items = [ 
    {id: 1, label: 'Item 0'}, 
    {id: 2, label: 'Item 1'} 
]; 
return { 
    list: function() { 
    return items; 
    }, 
    add: function(item) { 
    items.push(item); 
    } 
}; 

變量的項目是在工廠的頂部聲明,並在return語句訪問。

那麼,爲什麼不這項工作:

.factory('ItemService', ['$http', function($http) { 
var self = this; 
self.items = []; 
$http.get('/api_job_inspections/1/edit').then(function(response) { 
    //self.items = response.data; 
    self.items = [ 
     {id: 1, label: 'Item 0'}, 
     {id: 2, label: 'Item 1'} 
     ]; 
    }, function(errResponse) { 
    console.error('Error while fetching notes'); 
    }); 



return { 
    list: function() { 
    return self.items; 
    }, 
    add: function(item) { 
    self.items.push(item); 
    } 
}; 

我一直在使用VAR項目試圖= []像在第一個例子,但沒有得到恢復。使用這個語法什麼都不會返回。爲什麼?似乎有一個範圍問題,但它是什麼?

預先感謝您...

+0

當你期待的東西被退回? – 2014-10-31 08:43:17

+0

如果您想使用此服務,請使用服務代替工廠 – RahulB 2014-10-31 08:43:18

回答

1

看起來像一個範圍問題它沒有,而是一個異步的問題,你要確保Ajax調用完成?

嘗試在控制器執行以下操作:

angular.module('myApp').controller('ItemsController', 
     ['ItemService', '$scope', function(items, $scope) { 
      $scope.$watch(function() { 
       return items.list(); 
       }, function(newVal) { 
         console.log(newVal); 
        }); 
     }]); 

附:您可以使用服務,而不是使用工廠,它是工廠的包裝,基本上允許您使用this.something = function,這比工廠(imo)更方便。

1

在第一個示例中,在函數返回前items可用,而在第二個示例中,您正在進行異步調用。當你的服務注入你的控制器時,self.items還沒有被填充。

這兩個示例都有根本的不同,因此需要將不同的API暴露給服務使用者(即控制器)。

你應該考慮增加一個loadItems功能爲您服務:

... 
loadItems: function(){ 

    return $http.get('/api_job_inspections/1/edit') 
      .then(function(response){ 
        self.items = response.data; 
        return self.items; 
        }, 
        function(errResponse) { 
        console.error('Error while fetching notes'); 
        }); 
}, 
... 

在控制器中,那麼你可以這樣做:

.controller("myCtrl", function($scope, ItemService){ 
    ItemService.loadItems() 
     .then(function(items)){ 
     $scope.items = items; 
     // ItemService.list will also be available, so you can do: 
     // $scope.items = ItemService.list; 
     } 
}) 

這是不相關的使用.factory.service的建議。

此外,沒有必要創建一個延期對象$q.defer - $http已經返回一個.then可以承諾。

1

這是一個異步問題。您可以使用$q

app.factory('ItemService', ['$http', '$q', 
    function($http, $q) { 
    var self = this; 
    var service = {}; 
    self.items = []; 
    service.list = function(callback) { 
     var deferred = $q.defer(); 
     var cb=callback||angular.noop; 
     $http.get('/api_job_inspections/1/edit').success(function(data) { 
     //self.items = data; 
     self.items = [{ 
      id: 1, 
      label: 'Item 0' 
     }, { 
      id: 2, 
      label: 'Item 1' 
     }]; 
     deferred.resolve(self.items); 
     return cb(); 
     }).error(function(err) { 
     console.error('Error while fetching notes'); 
     deferred.reject(err); 
     return cb(err); 
     }.bind(this)); 
     return deferred.promise; 
    }; 
    service.add=function(item){ 
     self.items.push(item); 
    }; 
    return service; 
    } 
]); 

然後在你的控制器,你可以使用這樣的這項服務:

ItemService.list().then(function(data){ 
    $scope.items=data; 
    console.log(data); 
}); 
+0

感謝您的回覆。將標記爲正確答案。 – 2014-10-31 09:26:39

+0

不客氣...... – 2014-10-31 09:45:38

+0

@ s.alem,不需要創建延遲對象。 '$ http'已經返回一個承諾 – 2014-10-31 17:23:38