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

时间:2014-01-28 20:36:55

标签: javascript angularjs angularjs-scope angularjs-service angularjs-factory

我正在尝试构建一个工厂作为我的数据库模型的暂存区域,以及一个api来执行基本的CRUD调用。我希望能够通过将数据存储在服务或工厂中来访问数据,并保持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");
});

我知道我可以在控制器中解决一个承诺,但是根据我正在处理的项目的大小,我喜欢在服务中访问Folders模型的想法,而不必进行服务器调用每次进行更改时同步数据。

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()称为空对象后,它总是会回来。

有没有办法将这些数据作为文件夹模型的最新表示保存在Factory中,而不是每次都依赖于命中服务器?

在Rails 4 API上运行角度1.2.3。

2 个答案:

答案 0 :(得分: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;

    }

  };

});

答案 1 :(得分: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方法将服务转换为对象,该方法返回promise。我只是想证明这种技术可以实现的另一种方式。

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;
});