Javascript MEAN/AngularJS应用程序检查对象是否已发布
我有angularJS前端,我在后端使用express、node和mongo 我的情况如下:Javascript MEAN/AngularJS应用程序检查对象是否已发布,javascript,angularjs,node.js,mongodb,express,Javascript,Angularjs,Node.js,Mongodb,Express,我有angularJS前端,我在后端使用express、node和mongo 我的情况如下: //my data to push on server $scope.things = [{title:"title", other proprieties}, {title:"title", other proprieties}, {title:"title", other proprieties}] $scope.update = function() { $scope.things.fo
//my data to push on server
$scope.things = [{title:"title", other proprieties}, {title:"title", other proprieties}, {title:"title", other proprieties}]
$scope.update = function() {
$scope.things.forEach(function(t) {
Thing.create({
title: t.title,
//other values here
}, function() {
console.log('Thing added');
})
})
};
//where Thing.create its just an $http.post factory
//html part
<button ng-click="update()">Update Thing</button>
HTML部分如下所示:
//my data to push on server
$scope.things = [{title:"title", other proprieties}, {title:"title", other proprieties}, {title:"title", other proprieties}]
$scope.update = function() {
$scope.things.forEach(function(t) {
Thing.create({
title: t.title,
//other values here
}, function() {
console.log('Thing added');
})
})
};
//where Thing.create its just an $http.post factory
//html part
<button ng-click="update()">Update Thing</button>
//html部分
更新东西
然后,在同一页面上,用户可以更改$scope.things
,我的问题是,当我再次调用update()
时,所有内容都会被发布两次,因为实际上我就是这么做的
有人能告诉我如何检查“东西”是否已经发布到服务器上只是为了更新值($http.put),如果没有发布到服务器上则是$http.post
或者是另一种方法?我认为需要做出一些决定: 1) 您是否应该在用户单击“更新”按钮后发送请求(就像您当前所做的那样)?或者,当用户更改内容时(使用
ngChange
),您是否应该发送请求
2) 如果使用(1)的按钮方法,您是应该为每件事发送请求(就像您当前正在做的),还是应该首先检查该事是否已在前端更新/新建
3) 你如何处理这样一个事实:一些东西是新创建的,而另一些只是更新而已?多条路线?如果是,那么您如何知道将请求发送到哪个路由?同一条路线?怎么做
1. 对我来说,使用“更新”按钮的好处在于用户很清楚它是如何工作的。通过点击“更新”(之后可能会看到一条闪光消息),用户知道(并获得视觉反馈)东西已经更新 使用“更新”按钮的代价是可能会有不必要的请求。网络通信很慢,所以如果你有很多东西,对每件东西都有一个请求可能会非常慢 最终,对我来说,这似乎是一个UX vs.速度的决定。这取决于形势和目标,但我个人倾向于“更新”按钮
2. 这里的权衡似乎是在代码简单性和性能之间。更简单的解决方案是,对每件事情都提出请求,不管它是否已更新/新创建(对于以前存在且未更改的事情,不会造成任何伤害-它们根本不会更改) 更复杂但性能更高的方法是跟踪某个对象是否已更新/新创建。你可以添加一个名为
dirty
的标志来跟踪这件事
- 当用户单击创建新事物时,新事物将被赋予一个标记
dirty:true
- 当您查询以从数据库中获取所有内容时,它们都应该具有
(您是想将dirty:false
属性存储在数据库中,还是仅仅将其附加到服务器/前端取决于您)dirty
- 当用户更改现有内容时,
属性将设置为dirty
true
dirty
属性,您只能对dirty
对象发出请求:
$scope.things.forEach(function(thing) {
if (thing.dirty) {
// make request
}
});
正确的解决方案取决于您的具体情况,但我倾向于在代码简单性而不是性能方面犯错误
3. 如果您使用的是Mongoose,则需要在创建的文档中添加一个
\u id
字段(它也是as MongoDB本身)。因此,如果您没有覆盖此默认行为,并且没有明确阻止将此\u id
字段发送回客户机,那么它应该存在于先前创建的对象中,从而允许您将它们与新创建的对象区分开来(因为新创建的对象没有\u id
字段)
这样,您可以有条件地调用create
或update
,如下所示:
$scope.things.forEach(function(thing) {
if (thing._id) {
Thing.update(thing._id, thing);
}
else {
Thing.create(thing);
}
});
Thing.findByIdAndUpdate(id, newThing, { upsert: true }, function(err, doc) {
...
});
或者,您可以使用为您执行“创建或更新”的单个路由。您可以通过在update
调用中设置{upsert:true}
来实现这一点
在中,upsert
将检查文档是否与查询条件匹配。。。如果有匹配项,它会更新它,如果没有,它会创建它。在您的情况下,您可能会在猫鼬这样的环境中使用upsert
:
见SO post。@Adam Zemer巧妙地解决了我在评论中提出的问题,但我在一些问题上持不同意见 首先,要回答是否有更新按钮的问题,你必须问自己。用户是否有任何理由希望放弃所做的更改而不保存所做的工作。如果答案是否定的,那么我很清楚,更新不应该被放置,原因如下
$scope.update = function(changedThing) { // Using the ng-change you send the thing itself in parammeter
var $scope.saving = true; // To display the saving... message
Thing.update({ // This service call your method that update with upsert
title: changedThing.title,
//other values here
}).then( // If you made an http request, I suppose it returns a promise.
function success() {
$scope.saving = false;
console.log('Thing added');
},
function error() {
//handle errors
})
};
只是想澄清一下,当你第二次点击时,你想只更新一个arra吗