我一直在尝试将backbonejs和jqm一起使用。
我可以渲染主页。该页面有一个用户可以点击的列表。所选项目应显示详细信息页面,其中包含所选列表项的信息。详细信息页面是一个骨干视图,其中包含在项目视图对象中呈现的模板。
详细信息视图.render()生成html ok,我将主页面div标签的html设置为渲染项目的详细标记。它看起来像这样:
podClicked: function (event) {
console.log("PodListItemView: got click from:" + event.target.innerHTML + " id:" + (this.model.get("id") ? this.model.get("id") : "no id assigned") + "\n\t CID:" + this.model.cid);
var detailView = new PodDetailView({ model: this.model });
detailView.render();
},
详细视图的渲染如下所示:
render: function () {
this.$el.html(this.template({ podId: this.model.get("podId"), isAbout_Name: this.model.get("isAbout_Name"), happenedOn: this.model.get("happenedOn") }));
var appPageHtml = $(app.el).html($(this.el));
$.mobile.changePage(""); // <-- vague stab in the dark to try to get JQM to do something. I've also tried $.mobile.changePage(appPageHtml).
console.log("PodDetailView: render");
return this;
}
我可以看到详细信息的视图已经通过检查Chrome的开发工具html编辑器在页面上呈现,但它没有显示在页面上。我看到的只是一个空白页。
我尝试了$ .mobile.changePage()但是,如果没有URL,则会抛出错误。
如何让JQM将它的类标签应用于渲染的html?
HTML和模板如下所示:
<!-- Main Page -->
<div id="lessa-app" class="meditator-image" data-role="page"></div>
<!-- The rest are templates processed through underscore -->
<script id="app-main-template" type="text/template">
<div data-role="header">
<h1>@ViewBag.Title</h1>
</div>
<!-- /header -->
<div id="main-content" data-role="content">
<div id="pod-list" data-theme="a">
<ul data-role="listview" >
</ul>
</div>
</div>
<div id="main-footer" data-role='footer'>
<div id="newPod" class="ez-icon-plus"></div>
</div>
</script>
<script id="poditem-template" type="text/template">
<span class="pod-listitem"><%= isAbout_Name %></span> <span class='pod-listitem ui-li-aside'><%= happenedOn %></span> <span class='pod-listitem ui-li-count'>5</span>
</script>
<script id="page-pod-detail-template" type="text/template">
<div data-role="header">
<h1>Pod Details</h1>
</div>
<div data-role="content">
<div id='podDetailForm'>
<fieldset data-role="fieldcontain">
<legend>PodDto</legend>
<label for="happenedOn">This was on:</label>
<input type="date" name="name" id="happenedOn" value="<%= happenedOn %>" />
</fieldset>
</div>
<button id="backToList" data-inline="false">Back to list</button>
</div>
<div data-role='footer'></div>
</script>
提前感谢任何建议......这是否可行?
答案 0 :(得分:0)
我终于找到了办法。我的原始代码对此过程的成功有几个障碍。
首先要拦截jquerymobile的(v.1.2.0)changePage事件,如下所示: (我已经调整了jqm文档的大纲,并留在了有用的评论中:见http://jquerymobile.com/demos/1.2.0/docs/pages/page-dynamic.html )
$(document).bind("pagebeforechange", function (e, data) {
// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
if (typeof data.toPage === "string") {
// We are being asked to load a page by URL, but we only
// want to handle URLs that request the data for a specific
// category.
var u = $.mobile.path.parseUrl(data.toPage),
re = /^#/;
// don't intercept urls to the main page allow them to be managed by JQM
if (u.hash != "#lessa-app" && u.hash.search(re) !== -1) {
// We're being asked to display the items for a specific category.
// Call our internal method that builds the content for the category
// on the fly based on our in-memory category data structure.
showItemDetail(u, data.options); // <--- handle backbone view.render calls in this function
// Make sure to tell changePage() we've handled this call so it doesn't
// have to do anything.
e.preventDefault();
}
}
});
在项目的列表骨干视图事件声明中进行changePage()调用,该声明传递给podClicked方法,如下所示:
var PodListItemView = Backbone.View.extend({
tagName: 'li', // name of (orphan) root tag in this.el
attributes: { 'class': 'pod-listitem' },
// Caches the templates for the view
listTemplate: _.template($('#poditem-template').html()),
events: {
"click .pod-listitem": "podClicked"
},
initialize: function () {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
render: function () {
this.$el.html(this.listTemplate({ podId: this.model.get("podId"), isAbout_Name: this.model.get("isAbout_Name"), happenedOn: this.model.get("happenedOn") }));
return this;
},
podClicked: function (event) {
$.mobile.changePage("#pod-detail-page?CID='" + this.model.cid + "'");
},
clear: function () {
this.model.clear();
}
});
在'showItemDetail'函数中,url的查询部分被解析为项目主干模型的CID。我再次调整了上面显示的jquerymobile.com链接中提供的代码。
问题:我还在弄清楚,将showItemDetail()中的代码放在视图的render()方法中是否更好。具有已定义的功能似乎有损于骨干网的架构模型。另一方面,让render()函数知道调用JQM changePage似乎违反了“关注点分离”的原则。任何人都可以提供一些见解和指导吗?
// the passed url looks like #pod-detail-page?CID='c2'
function showItemDetail(urlObj, options) {
// Get the object that represents the item selected from the url
var pageSelector = urlObj.hash.replace(/\?.*$/, "");
var podCid = urlObj.hash.replace(/^.*\?CID=/, "").replace(/'/g, "");
var $page = $(pageSelector),
// Get the header for the page.
$header = $page.children(":jqmData(role=header)"),
// Get the content area element for the page.
$content = $page.children(":jqmData(role=content)");
// The markup we are going to inject into the content area of the page.
// retrieve the selected pod from the podList by Cid
var selectedPod = podList.getByCid(podCid);
// Find the h1 element in our header and inject the name of the item into it
var headerText = selectedPod.get("isAbout_Name");
$header.html("h1").html(headerText);
// Inject the item info into the content element
var view = new PodDetailView({ model: selectedPod });
var viewElHtml = view.render().$el.html();
$content.html(viewElHtml);
$page.page();
// Enhance the listview we just injected.
var fieldContain = $content.find(":jqmData(role=listview)");
fieldContain.listview();
// We don't want the data-url of the page we just modified
// to be the url that shows up in the browser's location field,
// so set the dataUrl option to the URL for the category
// we just loaded.
options.dataUrl = urlObj.href;
// Now call changePage() and tell it to switch to
// the page we just modified.
$.mobile.changePage($page, options);
}
所以上面提供了事件管道。
我遇到的另一个问题是页面设置不正确。最好将页面框架放在主html中,而不是将其放在下划线模板中以便稍后呈现。我认为避免jqm接管时html不存在的问题。
<!-- Main Page -->
<div id="lessa-app" data-role="page">
<div data-role="header">
<h1></h1>
</div>
<!-- /header -->
<div id="main-content" data-role="content">
<div id="pod-list" data-theme="a">
<ul data-role="listview">
</ul>
</div>
</div>
<div id="main-footer" data-role='footer'>
<div id="main-newPod" class="ez-icon-plus"></div>
</div>
</div>
<!-- detail page -->
<div id="pod-detail-page" data-role="page">
<div data-role="header">
<h1></h1>
</div>
<div id="detail-content" data-role="content">
<div id="pod-detail" data-theme="a">
</div>
</div>
<div id="detail-footer" data-role='footer'>
<a href="#lessa-app" data-role="button" data-mini="true">back</a>
</div>
</div>