Javascript Backbone.js:TypeError:Object#<;对象>;没有方法';解析';
我正在学习backbone.js,下面有个问题。我有一个名为Javascript Backbone.js:TypeError:Object#<;对象>;没有方法';解析';,javascript,backbone.js,Javascript,Backbone.js,我正在学习backbone.js,下面有个问题。我有一个名为历史的时代的集合。尝试app.History.create({from:0,until:1,stash:{from:null,until:null},_enabled:true})时,我在标题中得到了错误 这是我的密码: 模型 var app = app || {}; app.Era = Backbone.Model.extend({ defaults: { from: Number.NEGATIVE_INF
历史的时代的集合。尝试app.History.create({from:0,until:1,stash:{from:null,until:null},_enabled:true})时,
我在标题中得到了错误
这是我的密码:
模型
var app = app || {};
app.Era = Backbone.Model.extend({
defaults: {
from: Number.NEGATIVE_INFINITY,
until: Number.POSITIVE_INFINITY,
stash: {
from: null,
until: null
},
_enabled: true
},
toggle: function(){
if(this.get('_enabled')){
this.disable();
}else{
this.enable();
}
this.save();
},
enable: function(){
this.from = this.stash.from;
this.until = this.stash.until;
this.stash.from = null; // strictly speaking unnecssary
this.stash.until = null;
this._enabled = true;
},
disable: function(){
this.stash.from = this.from;
this.stash.until = this.until;
this.from = null;
this.until = null;
this._enabled = false;
},
enabled: function(){
return this._enabled;
},
});
var History = Backbone.Collection.extend({
model: app.Era,
localStorage: new Backbone.LocalStorage('karass-history'),
enabled: function(){
return this.filter(function(era){
return era.enabled();
});
},
nextOrder: function(){
if(!this.length){
return 1;
}
return this.last().get('order') + 1;
},
comparator: function( era ) {
return era.get('order');
},
comparatorFrom: function( era ){
return era.get('from');
},
comparatorUntil: function(era){
return era.get('until');
},
getFirstFrom: function(){
// todo
},
getLastUntil: function(){
// todo
},
getEraAt: function(time){
// todo
},
});
app.History = new History();
视图
app.AppView = Backbone.View.extend({
// bind to the karassApp div we set up in the html file
el: "#karassApp",
// Our template for the line of statistics at the bottom of the app.
statsTemplate: _.template( $('#stats-template').html() ),
// delegated events for creating new items, and clearing completed ones
events: {
'keypress #new-era-start': 'focusOnEnd',
'keypress #new-era-end': 'createEraOnEnter',
'click #disable-history': 'toggleEnabledAllEras'
},
// At initialization we bind to the relevant events on the 'eras'
// collection, when items are added or changed. Kick things off by
// loading any preexisting todos that might be saved in *localStorage*
initialize: function(){
//_.bindAll(this);
this.era_start = this.$('#new-era-start');
this.era_end = this.$('#new-era-end');
this.disableHistory = this.$('#disable-history');
this.$footer = this.$('#footer');
this.$main = this.$('#main');
window.app.History.on('add', this.addOneEra, this);
window.app.History.on('reset', this.addAllEras, this);
// window.app.History.on('add:true', this.addAllEras, this);
window.app.History.on('change:_enabled', this.filterOneEra, this);
window.app.History.on('filter', this.filterAllEras, this);
window.app.History.on('all', this.renderHistory, this);
app.History.fetch();
},
// Re-rendering the App just means refreshing the statistics -- the rest
// of the app doesn't change.
renderHistory: function(){
var era_count = app.History.length();
if(app.History.length){
this.$main.show();
this.$footer.show();
this.$footer.html(this.statsTemplate({
era_count: era_count,
}));
this.$('#filters li a')
.removeClass('selected')
.filter('[href=#/' + (app.EraFilter || '' ) + '"]')
.addClass('selected');
}else{
this.$main.hide();
this.$footer.hide();
}
this.disableHistory = !app.History.enabled();
},
// Add a single era item to the list by creating a view for it, and
// appending its element to the `<ul>`.
addOneEra: function(era){
var view = new app.EraView({ model: era });
$('#history').append(view.render().el);
},
addAllEras: function(){
this.$('#history').html('');
app.History.each(this.addOneEra, this);
},
filterOneEra: function(era){
era.trigger('visible');
},
filterAllEras: function(){
app.History.each(this.filterOne, this);
},
// Generate the attributes for the new Era Item
newEraAttributes: function(){
return {
from: this.era_start.val().trim(), // validation logic should probably go here: make sure it's a date that can be saved
until: this.era_end.val().trim(), // ditto
stash: {
from: null,
until: null
},
order: app.History.nextOrder(),
_enabled: true,
}
},
focusOnEnd: function(e){
if(e.which !== ENTER_KEY || !this.era_start.val().trim()){
return;
}
this.era_end.focus();
},
createEraOnEnter: function(e){
if(e.which !== ENTER_KEY || !this.era_start.val().trim()){
return;
}
app.History.create(this.newEraAttributes());
this.era_start.val('');
this.era_end.val('');
},
toggleEnabledAllEras: function(){
var enabled = !this.disableHistory.checked;
app.History.each(function(era){
era.toggle();
era.save();
});
}
});
app.EraView = Backbone.View.extend({
tagName: 'li',
template: _.template( $('#era-template').html() ),
// The DOM events specified to an item
events: {
'dblclick label': 'edit',
'keypress .edit .start': 'focusOnEnd',
'keypress .edit .end': 'updateOnEnter',
'blur .edit': 'close',
},
// The EraView listens for changes to its model, re-rendering. Since there's
// a one-to-one correspondence between an era and a EraView in this app,
// we set a direct reference on the model for convenience.
initialize: function(){
//_.bindAll(this);
this.model.on('change', this.render, this);
},
// Re-renders the era item to the current state of the model and
// updates the reference to the era's edit input within the view
render: function(){
this.$el.html( this.template(this.model.toJSON()));
this.era_start = this.$('.era-start');
this.era_end = this.$('.era-end');
return this;
},
// Switch this view into editing mode, displaying the input field
edit: function(){
this.$el.addClass('editing');
this.era_start.focus();
},
// Close the editing mode, saving changes to the era
close: function(){
var start = this.era_start.val().trim();
var end = this.era_end.val().trim();
if(start && end){
this.model.save({from: start, until: end});
}
this.$el.removeClass('editing');
},
focusOnEnd: function(e){
if(e.which !== ENTER_KEY || !this.era_start.val().trim()){
return;
}
this.era_end.focus();
},
updateOnEnter: function(e){
if(e.which !== ENTER_KEY || !this.era_end.val().trim()){
return;
}
this.close();
}
});
app.AppView=Backbone.View.extend({
//绑定到我们在html文件中设置的karassApp div
el:#卡拉萨普#,
//我们在应用程序底部的统计行模板。
statsTemplate:3;.template($('#stats template').html(),
//用于创建新项目和清除已完成项目的委派事件
活动:{
“按键#新时代开始”:“聚焦”,
“按键#新时代结束”:“CreateRoonenter”,
“单击#禁用历史记录”:“toggleEnabledAllEras”
},
//初始化时,我们绑定到“ERA”上的相关事件
//集合,当项目被添加或更改时。通过
//正在加载可能保存在*localStorage中的任何先前存在的TODO*
初始化:函数(){
//_.bindAll(这个);
this.era_start=this.$(“#新纪元开始”);
this.era_end=this.$(“#新纪元结束”);
this.disableHistory=this.$(“#禁用历史”);
this.$footer=this.$(“#footer”);
this.$main=this.$(“#main”);
window.app.History.on('add',this.addOneEra,this));
window.app.History.on('reset',this.addAllEras,this));
//window.app.History.on('add:true',this.addAllEras,this));
window.app.History.on('change:_enabled',this.filterneera,this);
window.app.History.on('filter',this.filterAllEras,this);
window.app.History.on('all',this.renderHistory,this);
app.History.fetch();
},
//重新呈现应用程序只意味着刷新统计数据——其余的
//应用程序的属性不会改变。
renderHistory:函数(){
var era_count=app.History.length();
如果(应用程序历史记录长度){
这是。$main.show();
这是。$footer.show();
this.$footer.html(this.statsTemplate({
纪元计数:纪元计数,
}));
此.$(“#过滤LIA”)
.removeClass('选定')
.filter(“[href=#/”+(app.EraFilter | |“)+”]))
.addClass(“选定”);
}否则{
这是。$main.hide();
这是。$footer.hide();
}
this.disableHistory=!app.History.enabled();
},
//通过创建单个era项目的视图,将其添加到列表中,然后
//将其元素附加到“”。
addOneEra:函数(era){
var view=new app.EraView({model:era});
$('#history').append(view.render().el);
},
addAllEras:function(){
这个.$('#history').html('');
app.History.each(this.addOneEra,this);
},
过滤器时代:功能(时代){
纪元触发(“可见”);
},
filterAllEras:function(){
app.History.each(this.filterOne,this);
},
//生成新纪元项目的属性
newEraAttributes:function(){
返回{
from:this.era_start.val().trim(),//验证逻辑可能应该在这里:确保它是可以保存的日期
直到:this.era_end.val().trim(),//同上
藏匿:{
from:null,
直到:空
},
顺序:app.History.nextOrder(),
_启用:对,
}
},
焦点:功能(e){
如果(e.which!==输入| | |!this.era|u start.val().trim()){
返回;
}
这个.era_end.focus();
},
CreateRaonenter:函数(e){
如果(e.which!==输入| | |!this.era|u start.val().trim()){
返回;
}
创建(this.newEraAttributes());
此.era_start.val(“”);
本.era_end.val('');
},
toggleEnabledAllEras:function(){
var enabled=!this.disableHistory.checked;
应用程序历史记录(每个功能(era){
era.toggle();
era.save();
});
}
});
app.EraView=Backbone.View.extend({
标记名:“li”,
模板:35;.template($('#era template').html()),
//指定给项的DOM事件
活动:{
“dblclick标签”:“编辑”,
'keypress.edit.start':'focusOnEnd',
'keypress.edit.end':'updateOnEnter',
'blur.edit':'close',
},
//EraView监听对其模型的更改,重新渲染
//此应用程序中era和EraView之间的一对一通信,
//为方便起见,我们在模型上设置了直接参考。
初始化:函数(){
//_.bindAll(这个);
this.model.on('change',this.render,this);
},
//将era项重新渲染为模型的当前状态,然后
//更新对视图中era编辑输入的引用
render:function(){
this.el.html(this.template(this.model.toJSON());
this.era_start=this.$(“.era start”);
this.era_end=this.$(“.era end”);
归还这个;
},
//将此视图切换到编辑模式,显示输入字段
编辑:函数(){
此.$el.addClass(“编辑”);
这个.era_start.focus();
},
//关闭编辑模式,保存对纪元的更改
关闭:函数(){
var start=this.era_start.val().trim();
var end=this.era_end.val().trim();
如果(开始和结束){
保存({from:start,until:end});
}
这个.el.removeClass('editing');
},
焦点:功能(e){
如果(e.which!==输入| | |!this.era|u start.val().trim()){
返回;
}
这个.era_end.focus();
},
更新输入:函数(e){
如果(e.which!==输入_键| |!this.era_end.val()。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Backbone.js • HistoryMVC</title>
</head>
<body>
<section id="karassApp">
<header id="header">
<h1>Karass</h1>
<input id="new-era-start" placeholder="Since when?" autofocus>
<input id="new-era-end" placeholder="Until when?" >
</header>
<section id="main">
<input id="disable-history" type="checkbox">
<label for="disable-history">Disable History, work on Snapshot instead</label>
<ul id="history"></ul>
</section>
<footer id="footer"></footer>
</section>
<div id="info">
No info here, traveller!
</div>
<script type="text/template" id="era-template">
<li>
<input class="era-start" placeholder="Since when?" value="<%= from %>">
<input class="era-end" placeholder="Until when?" value="<%= until %>">
<label>Edit</label>
</li>
</script>
<script type="text/template" id="stats-template">
<% if (era_count) { %>
<p>There are <%= era_count %> eras to display</p>
<% }else{ %>
<p>There are no eras to display, yet.</p>
<% } %>
</script>
<script src="js/lib/jquery-1.9.0.min.js"></script>
<script src="js/lib/underscore-min.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/lib/backbone.localStorage-min.js"></script>
<script src="js/models/era.js"></script>
<script src="js/models/history.js"></script>
<script src="js/views/app.js"></script>
<script src="js/views/era.js"></script>
</html>