Backbone.js 为什么主干视图不被渲染
下面是我用于简单任务添加的代码,视图无法渲染,我无法找到错误Backbone.js 为什么主干视图不被渲染,backbone.js,Backbone.js,下面是我用于简单任务添加的代码,视图无法渲染,我无法找到错误 <!doctype html> <html lang="en"> <head> <title>Calculator</title> <link rel="stylesheet" href="styles/bootstrap/css/bootstrap.min.css"> <script src="js/libs/jquery-1
<!doctype html>
<html lang="en">
<head>
<title>Calculator</title>
<link rel="stylesheet" href="styles/bootstrap/css/bootstrap.min.css">
<script src="js/libs/jquery-1.9.1.min.js"></script>
<script src="js/libs/underscore-min.js"></script>
<script src="js/libs/backbone-min.js"></script>
<script type="text/template" id="display-template">
<div class="row">
<div class="span4">
<%=content%>
</div>
</div>
</script>
<script language="javascript">
var cdate;
var tasks={};
var app = app || {};
// App view responsible for rendering app
app.TaskView = Backbone.View.extend({
el: $('#tasks'),
template: _.template($('#display-template').html()),
initialize: function () {
this.render();
},
render: function () {
console.log("render called");
console.log(this.template());
this.$el.html(this.template());
}
});
app.task = Backbone.Model.extend({
defaults:{
content:null
}
});
app.bUsers = Backbone.Collection.extend({
model : app.task,
initialize: function(models, args) {
this.bind('add', this.renderone);
this.bind('remove', this.destroy); },
renderone:function(user){
console.log(user);
var view = new app.TaskView({model: user});
},
destroy:function(user){
$(user.view.el).remove();
}
});
app.Users = new app.bUsers();
$(document).ready(function() {
cdate=new Date();
$("#cdate").html(new Date());
$("#pre").click(function(){
cdate=new Date(cdate.getTime()-(1*24*3600*1000));
$("#cdate").html(cdate);
});
$("#next").click(function(){
cdate=new Date(cdate.getTime()+(1*24*3600*1000));
$("#cdate").html(cdate);
});
$("#submit").click(function(){
if(tasks[cdate]==undefined) tasks[cdate]=[];
tasks[cdate].push($("#task").val());
// app.appView = new app.TaskView({
// model: new app.task({"content":$("#task").val()})
// });
var data ={"content":$("#task").val()};
app.Users.add(data);
});
});
</script>
</head>
<body>
<a id="pre" href="#">Prev</a>
<div id="cdate"></div>
<a id="next" href="#">Next</a>
<input type="text" id="task" ></input>
<input type="button" value="submit" id="submit" ></input>
<div id="tasks"></div>
</body>
计算器
cdate风险值;
var tasks={};
var-app=app |{};
//应用程序视图负责呈现应用程序
app.TaskView=Backbone.View.extend({
el:$(“#任务”),
模板:35;.template($('#显示模板').html()),
初始化:函数(){
这个。render();
},
渲染:函数(){
console.log(“渲染调用”);
console.log(this.template());
this.el.html(this.template());
}
});
app.task=Backbone.Model.extend({
默认值:{
内容:空
}
});
app.bUsers=Backbone.Collection.extend({
型号:app.task,
初始化:函数(模型、参数){
this.bind('add',this.renderone);
this.bind('remove',this.destroy);},
renderone:函数(用户){
console.log(用户);
var view=new app.TaskView({model:user});
},
销毁:功能(用户){
$(user.view.el).remove();
}
});
app.Users=新建app.bUsers();
$(文档).ready(函数(){
cdate=新日期();
$(“#cdate”).html(新日期());
$(“#pre”)。单击(函数(){
cdate=新日期(cdate.getTime()-(1*24*3600*1000));
$(“#cdate”).html(cdate);
});
$(“#下一步”)。单击(函数(){
cdate=新日期(cdate.getTime()+(1*24*3600*1000));
$(“#cdate”).html(cdate);
});
$(“#提交”)。单击(函数(){
如果(任务[cdate]==未定义)任务[cdate]=[];
tasks[cdate].push($(“#task”).val();
//app.appView=新建app.TaskView({
//模型:新的app.task({“content”:$(“#task”).val())
// });
var data={“content”:$(“#task”).val();
app.Users.add(数据);
});
});
哦,你有一些问题
为了回答您的特定问题,视图的呈现方法应该获取视图的模型实例,并从this.model.toJSON()
it中获取数据以传递给模板方法(toJSON
真正返回“JSONable”对象)
但这还不是全部
除了一些html问题外,您还存在风格问题
集合通常不应与视图相关,而只应与数据(*)相关。视图应该关注集合和模型。集合通过事件绑定与视图通信,我看到您正在这样做。但是,出于重用目的,您可能有多个组合视图希望侦听集合中的事件。通过在集合中设置事件绑定,可以有效地将集合限制为仅一次使用
视图可以做很多事情。当您可以编写视图代码来为自己添加DOM事件处理程序时,没有太多理由手动添加DOM事件处理程序
我已经有一段时间没有写主干了(不是自愿写的!),但总体上我发现最好有一个专门用于集合的视图,然后有一个单独的模型视图,集合视图可以根据发生的任何事件创建或销毁该视图
下面是对代码的一点清理,为您提供一个开始示例:
HTML:
(*)这当然是一个指导方针,而不是绝对规则。如果您认为集合可以作为某种工作流管理器等工作,那么这可能没问题,但这是一个高级主题
编辑:我内联使用模板,部分原因是我不信任JSFIDLE和内联“文本”脚本。我不推荐任何方法来处理这个问题,只是我在这里就是这样做的。您在控制台中看到任何错误吗?您看到了哪些日志?您不应该手动使用
toJSON()
。获得相同结果的更好、更惯用的方法是使用模型的attributes
属性this.template(model.attributes)
当我学习Backbone.js时,很多教程都使用了toJSON
,一些源代码甚至建议不要使用内部属性散列。我可以看到调用toJSON
可能很有用的情况,尽管它可能只适用于您只想将一整组数据从集合传递到某个备用模板解决方案的情况,而不是像我上面所做的那样按模型查看。但除此之外,当然,使用toJSON
可能会产生一堆不必要的副本,当这些副本被使用完时,垃圾收集器会经历更多的副本。
<a id="pre" href="#">Prev</a>
<div id="cdate"> </div>
<a id="next" href="#">Next</a>
<input type="text" id="task" />
<input type="button" value="add" id="submit" />
<div id="tasks"></div>
var defs = defs || {};
//first define the data handlers
defs.Task = Backbone.Model.extend({
defaults: function () {
return {
content: null,
addDate: (new Date()).toString()
};
}
});
defs.Users = Backbone.Collection.extend({
model: defs.Task
});
// App view responsible for rendering app
defs.SingleTaskView = Backbone.View.extend({
//since we can't control where the js is loaded, go ahead and make the template inline for jsFiddle demo.
tagName: 'div',
template: _.template('<div class="row"> <div class="span4"><%=content%></div> <em><%=addDate%></em> <button class="remove"> remove</remove> </div>'),
events: {
"click button.remove": "remove"
},
initialize: function (opts) {
this.model.on('change', this.render, this);
},
render: function () {
console.log("render called");
var modelBare = this.model.toJSON();
return this.$el.html(this.template(modelBare));
},
remove: function () {
//removes from local collection, does not delete on server
//for that, you'd want `this.model.destroy`
this.collection.remove(this.model);
//removes this view's element.
this.$el.remove();
}
})
defs.TasksView = Backbone.View.extend({
el: 'body',
events: {
"click #pre": "doPrevious",
"click #next ": "doNext",
"click #submit ": "doSubmit"
},
cdate: null,
initialize: function (opts) {
this.cdate = new Date();
this.render();
this.collection.on('add', this.renderone, this);
},
render: function () {
$("#cdate").html(this.cdate.toString());
},
doPrevious: function () {
this.cdate = new Date(this.cdate.getTime() - (1 * 24 * 3600 * 1000));
$("#cdate").html(this.cdate.toString());
},
doNext: function () {
this.cdate = new Date(this.cdate.getTime() + (1 * 24 * 3600 * 1000));
$("#cdate").html(this.cdate.toString());
},
doSubmit: function () {
var data = {
"content": $("#task").val()
};
this.collection.add([data]);
},
renderone: function (userModel) {
var view = new defs.SingleTaskView({
model: userModel,
collection: this.collection
});
this.$el.find('#tasks').append(view.render());
}
});
var app = app || {};
app.users = new defs.Users();
(function ($) {
$(document).ready(function () {
app.usersview = new defs.TasksView({
collection: app.users
});
});
})(jQuery);