Javascript AngularJS:在$http调用后访问工厂中存储的数据
我试图构建一个工厂,作为我的数据库模型的暂存区,以及一个执行基本CRUD调用的api。我希望能够通过将数据存储在服务或工厂中来访问数据,并保留api方法,以便在控制器中执行类似的操作Javascript AngularJS:在$http调用后访问工厂中存储的数据,javascript,angularjs,angularjs-scope,angularjs-service,angularjs-factory,Javascript,Angularjs,Angularjs Scope,Angularjs Service,Angularjs Factory,我试图构建一个工厂,作为我的数据库模型的暂存区,以及一个执行基本CRUD调用的api。我希望能够通过将数据存储在服务或工厂中来访问数据,并保留api方法,以便在控制器中执行类似的操作 $scope.folders = Folders.data(); // for a factory $scope.folders = Folders.data; // for a Service Folders.create({name: "My Stuff, $oid: { 5fwewe033333 }, u
$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");
});
目前我在控制器中使用的文件夹工厂与此类似
$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对象的持久性。它总是在我将Folders.data()作为空对象调用后返回
是否有办法将此数据作为文件夹模型的最新表示形式存储在工厂中,而不依赖于每次点击服务器
在Rails 4 API上运行angular 1.2.3。在本例中,服务本质上是数据。第一次注入服务时,会创建承诺并发出呼叫。该服务实际上是该数据的承诺,但当该呼叫返回时,该承诺将通过该数据得到解决。因此,第二次、第三次等注入服务时,不会再次发出呼叫-工厂已经完成了工作并返回了服务(本例中的承诺)
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;
});
这里有一个,其中我使用了两次数据。请注意控制台日志-此调用只进行过一次。在这个演示中,我使用返回承诺的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;
});
您可以将承诺作为对象存储在服务中。我在上面扩展了演示来演示 与前面的示例一样,http调用只进行一次,但这次承诺被添加到工厂创建的服务对象上的文件夹项中
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;
}
};
});
是的,我举个例子。我认为你最困惑的是,工厂创建了一项服务,然后就完成了。可以说,你们不能进入工厂。仅限服务。谢谢@m59,但是如果我想在服务中存储已解析的承诺,并且能够在不必再次访问服务器的情况下操作数据,该怎么办?因此,我可以像Folders.data[1]={folder_name:“New folder”}一样进行调用。我有一个相同的问题,我想将已解决的承诺存储在服务中,作为well@allencoded我不确定你有什么问题。我演示了两种方法可以做到这一点,它们工作得很好。它们保存返回的承诺,但我希望保存数据本身。@allencoded有效,这是一样的。你所说的不能从语义上理解。当然,您可以在呼叫返回时直接将数据应用于服务,但这并不能让您控制数据的使用方式。这些数据的使用者最终会在ajax调用返回之前尝试使用这些数据。当从异步源访问数据时,最好返回它的承诺。如果数据已经存在,这意味着
功能将立即启动。我添加了一个额外的plunkr,演示了一种更有用的方法,使您能够重复使用请求代码,但每个控制器仍然只发出一次请求。我个人认为,我将makeRequest对象封装为具有更大灵活性的自己的服务(如HTTP GET、POST、DELETE等),并将该服务注入到所有其他将访问我的api的服务中。我不认为这与我的回答有什么不同。有很多方法可以表达相同的概念。此外,您正在使用promise anti模式,方法是手动创建承诺,而不是使用$http
调用返回的承诺。@aaronroberson您的链接已失效?:)@AndersMetnik我的答案和这个答案之间唯一真正的区别是这个答案使用了promise anti模式(这是不好的),我更快地获取数据(小细节-易于更改)。我很乐意帮助您澄清您不理解的代码。请让我知道。@All。我做了一些研究,似乎这种模式确实有缺陷。我希望我能收回我的投票。如果有人看到这个,请使用@m59的答案。它更简单,也更可靠。