6

我正在嘗試構建一個工廠,作爲我的數據庫模型的暫存區域,以及執行基本CRUD調用的api。我希望能夠通過將數據存儲在服務或工廠中來訪問數據,並保留api方法,以便我可以在控制器中執行類似這些操作。

$scope.folders = Folders.data(); // for a factory 
$scope.folders = Folders.data; // for a Service 

Folders.create({name: "My Stuff, $oid: { 5fwewe033333 }, user_id: CurrentUser.id"}); 

目前我在控制器中使用這樣的文件夾工廠。

Folders.foldersData().success(function(data, status) { 
    $scope.folder = data; 
}) 
.error(function(data,status) { 
    Flash.warning("There was a problem fetching your data"); 
}); 

我知道我可以在控制器解決的承諾,但我的工作項目的大小,我喜歡在服務訪問文件夾模式的想法,與具有出每次進行更改時都會進行服務器調用以同步數據。

angular.module('cmsApp') 
    .factory('Folders', function($http, $q){ 

    var folders = {}; 
    var messageWarn = "Upload Retrival Failed."; 


    return { 
     get: function(){ 
     var defered = $q.defer(); 

     $http.get('/folders').success(function (data, status) { 
      defered.resolve(data); 
     }) 
     .error(function (data, status) { 
      defered.reject(); 
      Flash.warning(message_warn); 
     }); 
     defered.promise.then(function (promise) 
      folders = promise; 
     }); 
     }, 
     data: function(){ 
     return folders; 
    }, 
    }    
}); 

我的問題是,我不能讓文件夾對象要堅持我打電話Folders.get後()。在我將Folders.data()作爲空對象調用後,它總是返回。

有沒有辦法將這些數據保存在工廠中作爲不依賴於每次點擊服務器的文件夾模型的最新表示?

在Rails 4 API上運行angular 1.2.3。

+0

是的,我會舉一個例子。我認爲你感到困惑的主要原因是工廠創建了一個服務,然後就完成了。可以說,你不能訪問工廠。只有服務。 – m59

回答

10

您可以將承諾作爲服務中的對象存儲在服務中。我分叉上面的擴展演示來演示http://plnkr.co/edit/2HqQAiD33myyfVP4DWg3?p=preview

和前面的例子一樣,http調用只進行一次,但是這次promise將被添加到由工廠創建的服務對象上的文件夾項目中。


app.factory('myService', function($http, $q) { 

    return { 

    myObject: '', 

    get: function() { 
     // Create the deffered object 
     var deferred = $q.defer(); 

     if(!this.myObject) { 
     // Request has not been made, so make it 
     $http.get('my-file.json').then(function(resp) { 
      console.log('Making the call!'); 
      deferred.resolve(resp.data); 
     }); 
     // Add the promise to myObject 
     this.myObject = deferred.promise; 
     } 
     // Return the myObject stored on the service 
     return this.myObject; 

    } 

    }; 

}); 
+0

我添加了一個額外的plunkr,演示了一種更加實用的方法,使您可以重新使用請求代碼,但仍然只對每個控制器發出一次請求。請參閱http://plnkr.co/edit/2HqQAiD33myyfVP4DWg3?p=preview個人而言,我將makeRequest對象封裝爲具有更高靈活性的自有服務(如HTTP GET,POST,DELETE等),並將該服務注入其他所有服務服務將打我的api。 – aaronroberson

+0

一個很好的答案,值得更多的讚揚 – KeepCalmAndCarryOn

+0

我不明白這和我的答案有什麼不同。有很多方法來呈現相同的概念。此外,您通過手動創建承諾而不是使用'$ http'調用返回的承諾來使用諾言反模式。 – m59

2

在這個例子中,服務本質上是IS的數據。服務第一次被注入時,就會創建一個承諾,然後通話結束。該服務實際上是該數據的承諾,但是當該呼叫回來時,該承諾將與數據一起解決。因此,第二,第三等時間服務被注入,呼叫不會再次發生 - 工廠已經完成了它的工作並返回了服務(本例中的承諾)。

Live demo (click).

var app = angular.module('myApp', []); 

app.controller('myCtrl', function($scope, myService) { 
    myService.then(function(data) { 
    $scope.data = data 
    }) 
}); 

app.factory('myService', function($http, $q) { 
    //this runs the first time the service is injected 
    //this creates the service 

    var promise = $http.get('my-file.json').then(function(resp) { 
    return resp.data; 
    }); 

    return promise; 

}); 

下面是一個expanded demo我在其中使用數據的兩倍。注意控制檯日誌 - 該調用只能進行一次。在這個演示中,我使用返回承諾的get方法將該服務變爲對象。我只是想演示這種技術可以實施的另一種方式。

app.factory('myService', function($http, $q) { 

    console.log('Making the call!'); 
    var promise = $http.get('my-file.json').then(function(resp) { 
    return resp.data; 
    }); 

    var myService = { 
    get: function() { 
     return promise; 
    } 
    }; 

    return myService; 
}); 
+0

Thanks @ m59,但是如果我想將已解決的諾言存儲在服務中並且能夠操作數據而無需再次訪問服務器呢?所以我可以打電話像Folders.data [1] = {文件夾名稱:「新文件夾」} – armynante

+0

我有同樣的問題,我想在服務中存儲已解決的諾言以及 – allencoded

+0

@allencoded我不知道你有什麼問題'有。我演示了兩種可以完成的方法,並且它們工作正常。 – m59