AngularJS: POST 使用 $resource 更改服务器
AngularJS: POST changes to the server using $resource
我正在努力解决以下 AngularJS 问题。
我在服务器上的 .json 文件中有一个模型:
{
feedback: []
}
我的目标是将用户生成的数据从表单推送到反馈数组,因此每个反馈评论都表示为一个 javascript 对象。
我尝试使用一项服务,该服务 returns 一个 angular $resource 指向我的 .json 中的反馈数组。实现如下(baseURL只是指向localhost上的一个端口):
.service('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {
this.getFeedback = function() {
return $resource(baseURL + 'feedback', null, {'update': {method: 'PUT'}});
};
}])
然后我使用控制器按以下方式处理资源对象($scope.feedback
是一个存储用户通过表单生成的数据的对象):
.controller('FeedbackController', ['$scope', 'feedbackFactory', function($scope, feedbackFactory) {
$scope.sendFeedback = function() {
if ($scope.feedback.agree && ($scope.feedback.mychannel === "")) {
$scope.invalidChannelSelection = true;
console.log('incorrect');
}
else {
var feedbackData = feedbackFactory.getFeedback().query(
function(response) {
feedbackData = response;
}
);
feedbackData.push($scope.feedback);
feedbackData.$save();
}
}
}])
不幸的是,我经常收到以下错误:feedbackData.$save is not a function
。根据我目前阅读的所有内容,feedbackData 对象应该可以访问 $save 方法,但肯定有问题。我已经在这上面花了太多时间,所以我将非常感谢您的任何建议。
编辑。
经过一番努力,我尝试使用 feedback/:id
方法,所以我将服务更改为:
.service('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {
this.getFeedback = function() {
return $resource(baseURL + 'feedback/:id', null, {'update': {method: 'PUT'}});
};
}])
然后像这样将数据发送到服务器上的json:
var feedback = feedbackFactory.getFeedback().query(
function(response) {
feedback = response;
$scope.feedback.id = feedback.length;
feedbackFactory.getFeedback().save({id: $scope.feedback.id}, $scope.feedback);
}
);
这次我当然得到了我实际预期的错误 - POST 无法完成,因为 json 中的数组是一个空数组,所以我无法解决它和任何它的不存在元素的数字索引。但是,我觉得这种方法无论如何都更好,而且我缺少一些简单但重要的东西。
我认为这可能有效
else {
var feedbackData = feedbackFactory.getFeedback().query(
function(response) {
feedbackData = response;
feedbackData.push($scope.feedback);
feedbackData.$save();
}
);
}
查询需要时间才能获取数据,因此可以安全地将变量分配给成功函数中的请求响应
在您的情况下,我认为它会在您 getFeedBack()
完成获取数据后开始读取下一行
$resource
用于 RESTful API。在您的情况下,RESTful API 可能是这样的:
- 每个反馈都有一个 ID
/feedbacks
returns 反馈数组
/feedbacks/:id
returns 一个具体反馈
/feedbacks/new
和 POST 允许创建新反馈
query()
用于查询模型的所有实例(查询 /feedbacks
),因此需要一个数组。 get()
用于查询一个实例(通常是通过它的ID,在/feedbacks/:id
上查询)。
在您的例子中,您没有将单个反馈视为模型对象,而是将整个反馈数组视为模型对象。
您的代码存在一些问题:
query()
需要一个实例数组,您的 API 只是 returns 一个实例对象。我不确定 query()
在这种情况下的行为(我猜它 returns 是一个空数组,因为你调用 push
没有错误消息)。
- 如果它有效(在 API 返回数组的情况下),您不能对返回的变量调用
$save()
,因为 $save()
是一个方法实例对象。 query()
returns 个 数组 个实例。你想要的是使用 get()
.
现在用get()
代替query()
,还是不行。因为 get()
的结果是异步的,所以你应该在回调中做所有事情。 get()
returns a promise object,后面解析(当服务器回复AJAX请求时)。请在下面查看您的代码片段,评论它为什么不起作用。
var feedbackData = feedbackFactory.getFeedback().get(
function(response) {
/* This will be executed later. Note
that affecting response to feedbackData is not necessary,
since you already affected the result of .get(), which has
now resolved */
feedbackData = response;
}
);
/* feedbackData is just a promise, has not resolved into
instance object yet. $save() won't work */
feedbackData.push($scope.feedback);
feedbackData.$save();
现在正确的方法是:
var feedbackData = feedbackFactory.getFeedback().get(
function() {
/* Note that feedbackData is the object returned by your API,
not directly the array inside the object */
feedbackData.feedback.push($scope.feedback);
feedbackData.$save();
}
);
最后,$resource
是为 RESTful API 设计的。你的不是真的。我认为你最好直接使用 $http 。
好的,我终于找到了仍然使用 $resource 服务的问题的解决方案,所以我想这意味着它符合 CRUD 约束(解决方案基于这个很棒的博客 post: https://www.dunebook.com/introduction-to-resource-with-http-service-in-angularjs/#)
所以一切都非常简单。首先,我通过工厂设置我的资源:
.factory('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {
return $resource(baseURL + 'feedback/:id', null, {'update': {method: 'PUT'}});
}])
然后我创建了一个新的 $resource 实例,我在其中填充了一个对象,其中包含我从用户生成它的 $scope 中获取的反馈信息。然后我 $save 把它放回原来的地方 ($save 代表我处理所有事情):
var newFeedback = new feedbackFactory($scope.feedback);
newFeedback.$save();
希望它能为某人省去几个小时的头痛。
解决方案是 POST 而不是 PUT。 POSTing 也会自动为新数据分配一个 id。我用了一个服务,但是一个工厂也可以。
.service('feedbackFactory', ['$resource', 'baseURL', function ($resource, baseURL) {
this.getFeedback = function () {
return $resource(baseURL + 'feedback/:id', null, {
'save': {method: 'POST'}
});
};
}]);
然后控制器就这么简单
...
else {
feedbackFactory.getFeedback().save($scope.feedback);
...
}
您不需要在 getFeedback 函数中包含“:id”,但包含它将允许您发出特定的 ID 请求(如果您愿意的话),就像在本课程中的 IndexController 中使用的那样。
我正在努力解决以下 AngularJS 问题。
我在服务器上的 .json 文件中有一个模型:
{
feedback: []
}
我的目标是将用户生成的数据从表单推送到反馈数组,因此每个反馈评论都表示为一个 javascript 对象。
我尝试使用一项服务,该服务 returns 一个 angular $resource 指向我的 .json 中的反馈数组。实现如下(baseURL只是指向localhost上的一个端口):
.service('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {
this.getFeedback = function() {
return $resource(baseURL + 'feedback', null, {'update': {method: 'PUT'}});
};
}])
然后我使用控制器按以下方式处理资源对象($scope.feedback
是一个存储用户通过表单生成的数据的对象):
.controller('FeedbackController', ['$scope', 'feedbackFactory', function($scope, feedbackFactory) {
$scope.sendFeedback = function() {
if ($scope.feedback.agree && ($scope.feedback.mychannel === "")) {
$scope.invalidChannelSelection = true;
console.log('incorrect');
}
else {
var feedbackData = feedbackFactory.getFeedback().query(
function(response) {
feedbackData = response;
}
);
feedbackData.push($scope.feedback);
feedbackData.$save();
}
}
}])
不幸的是,我经常收到以下错误:feedbackData.$save is not a function
。根据我目前阅读的所有内容,feedbackData 对象应该可以访问 $save 方法,但肯定有问题。我已经在这上面花了太多时间,所以我将非常感谢您的任何建议。
编辑。
经过一番努力,我尝试使用 feedback/:id
方法,所以我将服务更改为:
.service('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {
this.getFeedback = function() {
return $resource(baseURL + 'feedback/:id', null, {'update': {method: 'PUT'}});
};
}])
然后像这样将数据发送到服务器上的json:
var feedback = feedbackFactory.getFeedback().query(
function(response) {
feedback = response;
$scope.feedback.id = feedback.length;
feedbackFactory.getFeedback().save({id: $scope.feedback.id}, $scope.feedback);
}
);
这次我当然得到了我实际预期的错误 - POST 无法完成,因为 json 中的数组是一个空数组,所以我无法解决它和任何它的不存在元素的数字索引。但是,我觉得这种方法无论如何都更好,而且我缺少一些简单但重要的东西。
我认为这可能有效
else {
var feedbackData = feedbackFactory.getFeedback().query(
function(response) {
feedbackData = response;
feedbackData.push($scope.feedback);
feedbackData.$save();
}
);
}
查询需要时间才能获取数据,因此可以安全地将变量分配给成功函数中的请求响应
在您的情况下,我认为它会在您 getFeedBack()
完成获取数据后开始读取下一行
$resource
用于 RESTful API。在您的情况下,RESTful API 可能是这样的:
- 每个反馈都有一个 ID
/feedbacks
returns 反馈数组/feedbacks/:id
returns 一个具体反馈/feedbacks/new
和 POST 允许创建新反馈
query()
用于查询模型的所有实例(查询 /feedbacks
),因此需要一个数组。 get()
用于查询一个实例(通常是通过它的ID,在/feedbacks/:id
上查询)。
在您的例子中,您没有将单个反馈视为模型对象,而是将整个反馈数组视为模型对象。
您的代码存在一些问题:
query()
需要一个实例数组,您的 API 只是 returns 一个实例对象。我不确定query()
在这种情况下的行为(我猜它 returns 是一个空数组,因为你调用push
没有错误消息)。- 如果它有效(在 API 返回数组的情况下),您不能对返回的变量调用
$save()
,因为$save()
是一个方法实例对象。query()
returns 个 数组 个实例。你想要的是使用get()
. 现在用
get()
代替query()
,还是不行。因为get()
的结果是异步的,所以你应该在回调中做所有事情。get()
returns a promise object,后面解析(当服务器回复AJAX请求时)。请在下面查看您的代码片段,评论它为什么不起作用。var feedbackData = feedbackFactory.getFeedback().get( function(response) { /* This will be executed later. Note that affecting response to feedbackData is not necessary, since you already affected the result of .get(), which has now resolved */ feedbackData = response; } ); /* feedbackData is just a promise, has not resolved into instance object yet. $save() won't work */ feedbackData.push($scope.feedback); feedbackData.$save();
现在正确的方法是:
var feedbackData = feedbackFactory.getFeedback().get(
function() {
/* Note that feedbackData is the object returned by your API,
not directly the array inside the object */
feedbackData.feedback.push($scope.feedback);
feedbackData.$save();
}
);
最后,$resource
是为 RESTful API 设计的。你的不是真的。我认为你最好直接使用 $http 。
好的,我终于找到了仍然使用 $resource 服务的问题的解决方案,所以我想这意味着它符合 CRUD 约束(解决方案基于这个很棒的博客 post: https://www.dunebook.com/introduction-to-resource-with-http-service-in-angularjs/#)
所以一切都非常简单。首先,我通过工厂设置我的资源:
.factory('feedbackFactory', ['$resource', 'baseURL', function($resource, baseURL) {
return $resource(baseURL + 'feedback/:id', null, {'update': {method: 'PUT'}});
}])
然后我创建了一个新的 $resource 实例,我在其中填充了一个对象,其中包含我从用户生成它的 $scope 中获取的反馈信息。然后我 $save 把它放回原来的地方 ($save 代表我处理所有事情):
var newFeedback = new feedbackFactory($scope.feedback);
newFeedback.$save();
希望它能为某人省去几个小时的头痛。
解决方案是 POST 而不是 PUT。 POSTing 也会自动为新数据分配一个 id。我用了一个服务,但是一个工厂也可以。
.service('feedbackFactory', ['$resource', 'baseURL', function ($resource, baseURL) {
this.getFeedback = function () {
return $resource(baseURL + 'feedback/:id', null, {
'save': {method: 'POST'}
});
};
}]);
然后控制器就这么简单
...
else {
feedbackFactory.getFeedback().save($scope.feedback);
...
}
您不需要在 getFeedback 函数中包含“:id”,但包含它将允许您发出特定的 ID 请求(如果您愿意的话),就像在本课程中的 IndexController 中使用的那样。