Javascript AngularJS:在$http调用后访问工厂中存储的数据

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

我试图构建一个工厂,作为我的数据库模型的暂存区,以及一个执行基本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");
});
目前我在控制器中使用的文件夹工厂与此类似

$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的答案。它更简单,也更可靠。