Javascript Backbone.js:视图对象为';未定义';
下面是我在backbone.js中的基本Todo应用程序代码:Javascript Backbone.js:视图对象为';未定义';,javascript,backbone.js,underscore.js,Javascript,Backbone.js,Underscore.js,下面是我在backbone.js中的基本Todo应用程序代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Hello World in Backbone.js</title> <style
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Hello World in Backbone.js</title>
<style type='text/css'>
#todoapp ul {
list-style-type: none;
}
#todo-list input.edit {
display: none;
}
#todo-list .editing label {
display: none;
}
#todo-list .editing input.edit {
display: inline;
}
</style>
</head>
<body>
<section id='todoapp'>
<header id='header'>
<h1>Todos</h1>
<input id='new-todo' placeholder='What needs to be done?'>
<div>
<a href="#/">all</a> |
<a href="#/pending">pending</a> |
<a href="#/completed">completed</a>
</div>
</header>
<section id='main'>
<ul id='todo-list'></ul>
</section>
</section>
<script type='text/x-handlebars-template' id='item-template'>
<div class='view'>
<input class='toggle' type='checkbox' {{checked}}>
<label>{{ title }} </label>
<input class='edit' value='{{ title }}'>
<button class='destroy'>remove</button>
</div>
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script>
<script type="text/javascript">
'use strict'
var App = {
Models: {},
Collections: {},
Views: {},
Router: {}
}
App.Models.Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false,
checked: ''
},
toggle: function(){
var completed = !this.get('completed')
this.save({
completed: completed,
checked: completed ? 'checked' : ''
});
}
});
App.Collections.TodoList = Backbone.Collection.extend({
model: App.Models.Todo,
localStorage: new Store('backbone-todo'),
completed: function(){
return this.filter(function(todo){
return todo.get('completed');
});
},
remaining: function(){
return this.without.apply(this, this.completed());
}
});
App.Views.Todo = Backbone.View.extend({
tagName: 'li',
template: Handlebars.compile($('#item-template').html()),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
this.input = this.$('.edit');
return this;
},
initialize: function(){
this.model.on('change', this.render, this);
this.model.on('destroy', this.remove, this);
},
events: {
'dblclick label': 'edit',
'keypress .edit': 'updateOnEnter',
'blur .edit': 'close',
'click .toggle': 'toggle',
'click .destroy': 'destroy'
},
edit: function(){
this.$el.addClass('editing');
this.input.focus();
},
updateOnEnter: function(e){
if(e.which == 13){
this.close();
}
},
close: function(){
var value = this.input.val().trim();
if(value){
this.model.save({title: value});
}
this.$el.removeClass('editing');
},
toggle: function(){
this.model.toggle();
},
destroy: function(){
this.model.destroy();
}
});
App.Views.TodoList = Backbone.View.extend({
el: '#todoapp',
filter: '',
initialize: function() {
this.input = this.$('#new-todo')
this.collection.on('add', this.addOne, this);
this.collection.on('reset', this.addAll, this);
this.collection.fetch();
},
events: {
'keypress #new-todo': 'createTodoOnEnter'
},
createTodoOnEnter: function(e) {
if(e.which !== 13 || !this.input.val().trim()){
return;
}
this.collection.create(this.newAttributes());
this.input.val('');
},
addOne: function(todo){
if(this.filter === 'completed'){
return;
}
var view = new App.Views.Todo({model: todo});
$('#todo-list').append(view.render().el);
},
addAll: function(){
this.$('#todo-list').html('');
switch(this.filter){
case 'pending':
_.each(this.collection.remaining(), this.addOne);
break;
case 'completed':
_.each(this.collection.completed(), this.addOne);
break;
default:
this.collection.each(this.addOne, this);
break;
}
},
newAttributes: function(){
return {
title: this.input.val().trim(),
completed: false
}
}
});
var todoList = new App.Collections.TodoList;
var todoListView = new App.Views.TodoList({collection: todoList});
App.Router = Backbone.Router.extend({
routes: {
'*filter': 'setFilter'
},
setFilter: function(params){
todoListView.filter = params.trim() || '';
todoListView.addAll();
}
});
var router = new App.Router;
Backbone.history.start();
</script>
</body>
</html>
Hello World in Backbone.js
#托多普大学{
列表样式类型:无;
}
#todo list input.edit{
显示:无;
}
#待办事项列表。编辑标签{
显示:无;
}
#待办事项列表。编辑输入。编辑{
显示:内联;
}
待办事项
|
|
{{title}}
去除
“严格使用”
变量应用={
型号:{},
集合:{},
视图:{},
路由器:{}
}
App.Models.Todo=Backbone.Model.extend({
默认值:{
标题:“”,
已完成:错误,
选中:“”
},
切换:函数(){
var completed=!this.get('completed'))
这个,救命({
已完成:已完成,
选中:已完成?“选中”:”
});
}
});
App.Collections.TodoList=Backbone.Collection.extend({
型号:App.Models.Todo,
localStorage:新存储区('backbone-todo'),
已完成:函数(){
返回此.filter(函数(todo){
返回todo.get('completed');
});
},
剩余:函数(){
返回this.without.apply(this,this.completed());
}
});
App.Views.Todo=Backbone.View.extend({
标记名:“li”,
模板:handlebar.compile($('#项模板').html()),
render:function(){
this.el.html(this.template(this.model.toJSON());
this.input=this.$('.edit');
归还这个;
},
初始化:函数(){
this.model.on('change',this.render,this);
this.model.on('destroy',this.remove,this);
},
活动:{
“dblclick标签”:“编辑”,
'keypress.edit':'updateOnEnter',
'blur.edit':'close',
'点击.切换':'切换',
“单击。销毁”:“销毁”
},
编辑:函数(){
此.$el.addClass(“编辑”);
this.input.focus();
},
更新输入:函数(e){
如果(e.which==13){
这个。关闭();
}
},
关闭:函数(){
var value=this.input.val().trim();
如果(值){
this.model.save({title:value});
}
这个.el.removeClass('editing');
},
切换:函数(){
this.model.toggle();
},
销毁:函数(){
this.model.destroy();
}
});
App.Views.TodoList=Backbone.View.extend({
el:'托多普',
筛选器:“”,
初始化:函数(){
this.input=this.$(“#新任务”)
this.collection.on('add',this.addOne,this);
this.collection.on('reset',this.addAll,this));
this.collection.fetch();
},
活动:{
“按键#新待办事项”:“createTodoOnEnter”
},
createTodoOnEnter:函数(e){
如果(e.which!==13 | |!this.input.val().trim()){
返回;
}
this.collection.create(this.newAttributes());
这个.input.val(“”);
},
addOne:函数(todo){
如果(this.filter===“已完成”){
返回;
}
var view=newapp.Views.Todo({model:Todo});
$(“#待办事项列表”).append(view.render().el);
},
addAll:function(){
这个.$('#待办事项列表').html('';
开关(此.过滤器){
“未决”案件:
_.each(this.collection.remaining(),this.addOne);
打破
案件‘已完成’:
_.each(this.collection.completed(),this.addOne);
打破
违约:
this.collection.each(this.addOne,this);
打破
}
},
newAttributes:function(){
返回{
标题:this.input.val().trim(),
已完成:false
}
}
});
var todoList=new App.Collections.todoList;
var todoListView=newapp.Views.TodoList({collection:TodoList});
App.Router=Backbone.Router.extend({
路线:{
“*过滤器”:“设置过滤器”
},
setFilter:函数(参数){
todoListView.filter=params.trim();
todoListView.addAll();
}
});
var路由器=新的应用程序路由器;
Backbone.history.start();
在App.Views.TodoList
的addOne
方法中,条件if(this.filter=='completed')
导致错误未捕获类型错误:无法读取未定义的属性'filter'。为什么这个(todoListView对象)没有定义?\uu0。每个()
都可以接受一个可选的上下文。试试这个:
case 'pending':
_.each(this.collection.remaining(), this.addOne, this);
break;
case 'completed':
_.each(this.collection.completed(), this.addOne, this);
break;
你需要找出addOne的来电者
似乎有4种用法
this.collection.on('add', this.addOne, this);
this.collection.each(this.addOne, this);
您将此作为上下文传递。这应该没问题
您询问的错误应该是以下用法之一。
如果要将其用作函数中的视图对象,请将其分别传入
_.each(this.collection.remaining(), this.addOne);
_.each(this.collection.completed(), this.addOne);
到
_.each(this.collection.remaining(), this.addOne, this);
_.each(this.collection.completed(), this.addOne, this);