我正在尝试一个简单的项目,试图学习jQuery Mobile和Backbone.js,并遇到了一个问题。该项目是一个简单的笔记记录应用程序,它使用HTML5本地存储保存笔记。
该程序正在客户端创建页面,我正在尝试使用$ .mobile.initializePage()来使结果页面按预期使用JQM。相反的是,initializePage()永远不会完成,并且生成的加载微调器永远不会消失。
我检查了在客户端创建的HTML,据我所知,一切都是正确的。我还尝试使用chrome中的控制台触发器('create')和createPage()来查看是否正在创建页面,但这并不能解决问题。没有错误被抛出,我在过去2天内无法找到解决方案。我的代码如下。
HTML页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Local Notes</title>
<link rel="stylesheet" href="css/jquery.mobile-1.0.1.css" media="screen" title="jquery mobile" charset="UTF-8"/>
</head>
<body>
<!-- Home Page -->
<div id="home" data-role="page">
<div data-role="header">
<h1>Local Notes</h1>
</div>
<div data-role="content">
<a href="#new" data-rel="dialog" data-transition="pop" data-role="button" data-icon="plus" data-theme="b">New</a>
<ul data-role="listview" data-inset="true">
<li><a href="#all">All Notes</a></li>
<li><a href="#nearest">Nearest Notes</a></li>
</ul>
</div>
</div>
<!-- New Note Form-->
<div id="new" data-role="page">
<div data-role="header">
<h1>New Note</h1>
</div>
<div data-role="content">
<form action="#" method="post">
<div data-role="fieldcontain">
<label for="title">Title</label>
<input id="title" name="title" value="" />
</div>
<div data-role="fieldcontain">
<label for="body">Body</label>
<textarea id="body" name="body" value=""></textarea>
</div>
<button data-icon="check" data-theme="b">Save</button>
</form>
</div>
</div>
<!-- List of Notes -->
<div id="all" data-role="page">
<div data-role="header">
<a href="#home" data-role="button" data-icon="arrow-l" data-rel="back">Back</a>
<h1>All Notes</h1>
</div>
<div data-role="content">
<ul data-role="listview" id="all_notes">
</ul>
</div>
</div>
<!-- List of Note detail pages -->
<div id="note-detail-list"></div>
<!-- Note list template -->
<script type="text/template" id="note-list-item-template">
<a href="#note_<%= note.id %>"><%= note.get('title') %></a>
</script>
<!-- Note detail template -->
<script type="text/template" id="note-detail-template">
<div data-role="header">
<a href="#home" data-role="button" data-icon="arrow-l" data-rel="back">Back</a>
<h1><%= note.get('title') %></h1>
</div>
<div data-role="content"><%= note.get('body') %></div>
</script>
<script src="js/jquery-1.7.1.js"></script>
<script src="js/underscore.js"></script>
<script src="js/backbone.js"></script>
<script src="js/backbone.localStorage.js"></script>
<script src="js/jquery.mobile-1.0.1.js"></script>
<script src="js/application.js"></script>
</body>
</html>
的Javascript
var NotesApp = (function(){
var App = {
stores: {},
views:{},
collections:{}
}
// Initialize localStorage Data Store
App.stores.notes = new Store('notes');
// Note model
var Note = Backbone.Model.extend({
// Use localStorage datastore
localStorage: App.stores.notes,
initialize: function(){
if(!this.get('title')){
this.set({title: "Note @ " + Date() })
};
if(!this.get('body')){
this.set({body: "No Content"})
};
}
})
// Collections
var NoteList = Backbone.Collection.extend({
// This collection is composed of Note objects
model: Note,
// Set the localStorage datastore
localStorage: App.stores.notes,
initialize: function(){
var collection = this;
this.localStorage.bind('update', function(){
collection.fetch();
})
}
})
// Views
var NewFormView = Backbone.View.extend({
events: {
"submit form": "createNote"
},
createNote: function(e){
var attrs = this.getAttributes(),
note = new Note();
note.set(attrs);
note.save();
// Stop browser from actually submitting the form
e.preventDefault();
// Stop jQuery mobile from doing its form magic
e.stopPropagation();
// Close dialog
$('.ui-dialog').dialog('close');
this.reset();
},
getAttributes: function(){
return {
title: this.$('form [name=title]').val(),
body: this.$('form [name=body]').val()
}
},
reset: function(){
this.$('input, textarea').val('');
}
});
var NoteListView = Backbone.View.extend({
initialize: function(){
_.bindAll(this, 'addOne', 'addAll');
this.collection.bind('add', this.addOne);
this.collection.bind('reset', this.addAll);
this.collection.fetch();
},
addOne: function(note){
var view = new NoteListItemView({model: note});
$(this.el).append(view.render().el);
if(this.el.hasClass('ui-listview')){
$(this.el).listview('refresh');
}
},
addAll: function(){
$(this.el).empty();
this.collection.each(this.addOne);
}
});
var NoteListItemView = Backbone.View.extend({
tagName: 'LI',
template: _.template($('#note-list-item-template').html()),
initialize: function(){
_.bindAll(this, 'render')
this.model.bind('change', this.render)
},
render: function(){
$(this.el).html(this.template({ note: this.model }))
return this;
}
});
var NoteDetailView = Backbone.View.extend({
tagName: "DIV",
template: _.template($('#note-detail-template').html()),
initialize: function(){
_.bindAll(this, 'render');
$(this.el).attr({
'data-role': 'page',
'id': "note_" + this.model.id
});
this.model.bind('change', this.render);
},
render: function(){
$(this.el).html(this.template({note: this.model}));
return this;
}
});
var NoteDetailList = Backbone.View.extend({
el: $('#note-detail-list'),
initialize: function(){
_.bindAll(this, 'addOne', 'addAll', 'render');
this.collection.bind('add', this.addOne);
this.collection.bind('reset', this.addAll);
this.collection.fetch();
},
addOne: function(note){
var view = new NoteDetailView({model: note});
$(this.el).append(view.render().el);
if($.mobile){
$.mobile.initializePage();
}
},
addAll: function(){
$(this.el).empty();
this.collection.each(this.addOne);
}
});
App.collections.all_notes = new NoteList()
App.views.new_form = new NewFormView({
el: $('#new')
});
App.views.list_alphabetical = new NoteListView({
el: $('#all_notes'),
collection: App.collections.all_notes
})
App.views.notes = new NoteDetailList({
collection: App.collections.all_notes
})
return App;
})()
更新
在深入研究这个问题之后,我有更多关于此错误的详细信息。代码正在生成动态创建的页面,使用listview中的链接无法访问它们。这些链接引用了哈希,其中包含我想要访问的DIV的ID。 DIV具有data-role = page和data-url = #ID。可以通过Chrome和Firefox中的控制台使用以下代码访问这些相同的页面。
$.mobile.changePage($('#DIV ID'))
此工作正常,页面格式正确。根据JQM文档,有一个问题,如果它们缺少data-url属性,链接将不起作用,但它应该在JQM 1.0版本中修复。