服务函数中的AngularJS $资源

时间:2014-10-24 19:57:41

标签: javascript angularjs cordova angularjs-service angularjs-resource

我正在使用网络技术(angular.js等)构建Android应用程序的团队和Phonegap将项目转变为Android应用程序。我们对AngularJS相当新,并且遇到了将服务集成到我们的代码中的问题。我们正在尝试做一些基本的服务器调用,它们作为常规代码工作,但我们正在尝试将它们作为服务,因此我们不会在整个地方复制它。我们使用Phonegap localStorage插件在手机的HTML5本地存储上存储数据库对象的ID。

这是我们的代码:

.service("contactServer", function($resource, $http, baseUrl) {
    // Initialize resource and modify methods s.t. create POSTS and save PUTS.
    this.post = function() {
        alert("Starting post");
        var item = {"name": model.userName, "position": model.position};
        alert("Creating resource");
        var serverResource = $resource(baseUrl,
            {create: {method: "POST"}, save: {method: "PUT"}});
        alert("Created resource");
        new serverResource.create(item).then(function(data, status, headers, config) {
            alert("id: " + data._id);
            window.localStorage.setItem("DBid", data._id);
        }, function(data, status, headers, config) {
            alert(JSON.stringify(['Error', data, status, headers, config]))
        })
    }

    this.put = function() {
        alert("Starting put");
        var item = {"name": model.userName, "position": model.position, "id": window.localStorage.getItem("DBid")};
        alert("Creating resource");
        var serverResource = $resource(baseUrl + "/:id", {id: "@id"},
            {create: {method: "POST"}, save: {method: "PUT"}});
        alert("Created resource");
        new serverResource(item).save().then(function(data, status, headers, config) {
            alert(JSON.stringify(['Success', data, status, headers, config]));
        }, function(data, status, headers, config) {
            alert(JSON.stringify(['Error', data, status, headers, config]));
        })
    }
})

baseUrl是我们数据库的URL链接。我们在这里称呼服务:

.run(function(contactServer) {
    document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady() {

        if (window.localStorage.getItem("DBid") == null) {
            alert("no DBid");
            contactServer.post();
        }
        else {
            alert("Retrieved stored DBid: " + window.localStorage.getItem("DBid"));
            contactServer.put();
        }

    }
})

deviceready是一个Phonegap事件,当应用程序加载到用户的手机上时会触发该事件。我们想在几个控制器中调用这些服务,但最初也要在此运行函数中调用。

在运行功能中调用后,代码会激活“开始发布”警报,但随后会中断。我们使用$ resource是错误的吗? (它被正确列为依赖项)。我们是否实施了错误的服务?

4 个答案:

答案 0 :(得分:2)

希望这能以正确的方式帮助您:

  var app = angular.module("app", ["ngResource"]);

  app.service("contactServer", function($resource, $http) {
      // Initialize resource and modify methods s.t. create POSTS and save PUTS.
      var baseUrl = "test";
      var model = {
        userName: "",
        position: ""
      }

      var serverResource = $resource(baseUrl + "/:id", {id: "@id"},
              {create: {method: "POST"}, save: {method: "PUT"}});

      this.post = function() {
          alert("Starting post");
          var item = {"name": model.userName, "position": model.position};
          serverResource.create(item).then(function(data, status, headers, config) {
              alert("id: " + data._id);
              window.localStorage.setItem("DBid", data._id);
          }, function(data, status, headers, config) {
              alert(JSON.stringify(['Error', data, status, headers, config]))
          })
      }

      this.put = function() {
          alert("Starting put");
          var item = {"name": model.userName, "position": model.position, "id": window.localStorage.getItem("DBid")};
          serverResource.save(item).then(function(data, status, headers, config) {
              alert(JSON.stringify(['Success', data, status, headers, config]));
          }, function(data, status, headers, config) {
              alert(JSON.stringify(['Error', data, status, headers, config]));
          })
      }
  });

  app.run(function(contactServer) {
      document.addEventListener("deviceready", onDeviceReady, false);

      function onDeviceReady() {

          if (window.localStorage.getItem("DBid") == null) {
              alert("no DBid");
              contactServer.post();
          }
          else {
              alert("Retrieved stored DBid: " + window.localStorage.getItem("DBid"));
              contactServer.put();
          }

      }

  });

为了使它更好一些,我会从服务serverResource返回contactServer对象,并使用资源的保存和控制器中的创建方法并运行块(也解决那里的promises)

简而言之:您必须使用$resource(外部服务函数声明)创建$resource()一次,并在函数中使用它。也不需要new关键字,可能会破坏这一点。

答案 1 :(得分:2)

您遇到的问题是您的方法的定义 改变这个

var serverResource = $resource(baseUrl,
            {create: {method: "POST"}, save: {method: "PUT"}});

进入这个:

var serverResource = $resource(baseUrl, {},
            {create: {method: "POST"}, save: {method: "PUT"}});

查看documentation

因为你的方法不是非Get实例,你应该执行它们,如下所示:

new serverResource.$create(item).then(function(data, status, headers, config) {
            //content
        }, function(data, status, headers, config) {
            //error content
        })

文档说:

  

HTTP GET“class”操作:Resource.action([parameters],[success],[error])

     

非GET“类”操作:Resource.action([parameters],postData,[success],[error])

     

非GET实例操作:实例。$ action([参数],[成功],[错误])

我建议您使用console.log而不是警报来调试代码,警报可能会在摘要周期中产生一些问题。

让我给你一个替代解决方案:

.factory('contactServer', ['$resource', function($resource){
    var baseUrl = 'testing/:id';
    var resource = $resource(baseUrl, {id: '@id'}, {update: {method: 'PUT'}});
    return resource;
}]);

你会用它作为:

.run(function(contactServer) {
    document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady() {

        if (window.localStorage.getItem("DBid") == null) {
            alert("no DBid");
            //item creation
            var instance = new contactServer(item);
            contactServer.$save(item).then(function(res){
                 window.localStorage.setItem("DBid", res._id);
            });
        }
        else {
            alert("Retrieved stored DBid: " + window.localStorage.getItem("DBid"));
            var id = //theId;
            var updateObject = //item update;
            var instance = new contactServer();
            contactServer.$update({id: id}, updateObject).then(function(res){
                console.log('object updated!');
            });
        }

    }
});

..或类似的东西。希望这有帮助。

答案 2 :(得分:1)

你不需要改变

serverResource.create(item).then(function(data, status, headers, config) {...}

serverResource.create(item).$promise.then(function(data, status, headers, config) {...}
                            --------

https://docs.angularjs.org/api/ngResource/service/$resource 在“信用卡资源”示例

的末尾

答案 3 :(得分:0)

实际上这是一个有趣的问题。

作为解决方法,如果您想构建可重用的实例来进行http查询,我建议您使用Restangular。在这种情况下,它有一些优点: - 它使用promise而不是返回空对象并用新数据填充它。 (它实际上是ngResource的行为)。因此,您可以在解决部分重复使用您的服务。 - 您不必为每个请求创建一个$ resource对象。 - 支持很多http方法。

以下是示例:

angular.module( '应用程序')。服务('accountService'function(Restangular){

   var baseAccounts = Restangular.all('accounts');

   this.getAll = function(){
      return baseAccounts.getList();
   }

   this.getById = function(id){
       /accounts/profile/{id}
       return baseAccounts.one('profile',id)
   }

})

您可以在此处找到更多信息。 https://github.com/mgonto/restangular#differences-with-resource