我是骨干新手,想要测试处理待办事项列表的简单脚本。这是我到目前为止使用的代码:
(function() {
window.App = {
Models: {},
Collections: {},
Views: {}
};
window.template = function(id) {
return _.template($('#' + id).html());
}
App.Models.Task = Backbone.Model.extend({
validate: function(attributes) {
if ( !$.trim(attributes.title) ) {
return 'Invalid title';
}
}
});
App.Collections.Tasks = Backbone.Collection.extend({
model: App.Models.Task
});
App.Views.Task = Backbone.View.extend({
tagName: 'li',
template: template('taskTemplate'),
initialize: function () {
this.model.on('change', this.render, this);
this.model.on('destroy', this.remove, this);
},
events: {
'click .edit': 'editTask',
'click .delete': 'destroy'
},
destroy: function() {
if (confirm('Are you sure?')) {
this.model.destroy();
}
},
remove: function() {
this.$el.remove();
},
editTask: function() {
var newTaskTitle = prompt('New title:', this.model.get('title'));
this.model.set('title', newTaskTitle, {validate: true});
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
App.Views.AddTask = Backbone.View.extend({
el: 'form#addTask',
initialize: function() {
},
events: {
'submit': 'submit'
},
submit: function(event) {
event.preventDefault();
var newTaskTitle = $(event.currentTarget).find('input[type=text]').val();
var task = new App.Models.Task({ title: newTaskTitle });
this.collection.add(task, {add: true, merge: false, remove: false});
}
});
App.Views.Tasks = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
this.collection.on('add', this.addOne, this);
},
render: function() {
this.collection.each(this.addOne, this);
return this;
},
addOne: function(task) {
var taskView = new App.Views.Task({ model: task });
this.$el.append(taskView.render().el);
}
});
var tasks = new App.Collections.Tasks([
{
title: 'Go to store',
priority: 4
},
{
title: 'Go to mall',
priority: 3
},
{
title: 'Get to work',
priority: 5
}
]);
var addTaskView = new App.Views.AddTask({ collection: tasks });
var tasksView = new App.Views.Tasks({ collection: tasks });
$('div.tasks').append(tasksView.render().el);
})();
所以模型验证工作正常......唯一的pb是collection.add不验证新添加的模型....是强制验证的一种方法吗?
谢谢, 拉雷什
答案 0 :(得分:2)
来自fine manual:
验证
model.validate(attributes, options)
[...]默认情况下,验证在
save
之前调用,但也可以 如果set
通过,则在{validate:true}
之前调用。
Collection#add
不会致电save
,也不会使用set
选项致电validate: true
。如果您想在add
期间进行验证,请说明:
collection.add(models, { validate: true });
这将validate:true
一直到Model#set
。
快速浏览一个简化示例可能会有所帮助:
var M = Backbone.Model.extend({
set: function() {
console.log('setting...');
Backbone.Model.prototype.set.apply(this, arguments);
},
validate: function() {
console.log('validating...');
return 'Never!';
}
});
var C = Backbone.Collection.extend({
model: M
});
var c = new C;
c.on('add', function() {
console.log('Added: ', arguments);
});
c.on('invalid', function() {
console.log('Error: ', arguments);
});
现在,如果我们这样做(http://jsfiddle.net/ambiguous/7NqPg/):
c.add(
{ where: 'is', pancakes: 'house?' },
{ validate: true }
);
您会看到使用set
调用validate: true
,将调用validate
,您将收到错误消息。但如果你这样说(http://jsfiddle.net/ambiguous/7b2mn/):
c.add(
{ where: 'is', pancakes: 'house?' },
{add: true, merge: false, remove: false} // Your options
);
您会看到set
在没有validate: true
的情况下被调用,validate
将不被调用,模型将被添加到集合中。< / p>
上述行为非常强烈暗示但未明确指定,因此您可能不想信任它。 Model#initialize
确实说:
您可以传递属性的初始值,该值在模型上为
set
。
和set
明确提到了validate
选项。但是,无法保证Collection#add
会向模型构造函数或set
发送选项,或者模型的构造函数会将选项发送到set
。因此,如果你想要真正的偏执和未来证明,你可以快速检查这个“选项一直到set
”行为到您的测试套件;然后,如果它改变了你就会知道它并且你可以解决它。
答案 1 :(得分:1)
如果将选项传递给集合添加方法,则不会调用验证方法,并且由于此情况下的参数都设置为默认值,因此无需传递它们
this.collection.add(task);
你可能想看看这个问题。 Prevent Backbone.js model from validating when first added to collection