我正在使用网络技术(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是错误的吗? (它被正确列为依赖项)。我们是否实施了错误的服务?
答案 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"}});
因为你的方法不是非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