jsFiddle http://jsfiddle.net/nAgfQ/2/(有关说明和解决方法,请参阅HTML部分的顶部。)
方案
我使用jQuery Mobile(1.4.2)和KnockoutJS(3.1.0)构建了一个非常简单的基于标签的单页Web应用程序,用于向业务用户显示数据。
代码
这是JS:
$(function () {
var Tab = function (Title, TabID) {
var self = this;
self.Title = ko.observable(Title);
self.TabID = ko.observable(TabID);
self.TabHref = ko.computed(function () {
return '#' + self.TabID();
});
};
function DashboardViewModel() {
var self = this;
self.Title = ko.observable();
self.DashboardID = ko.observable();
self.tabs = ko.observableArray([
new Tab("Tab 1", "tabs-1", []),
new Tab("Tab 2", "tabs-2", [])]);
self.refreshTabs = function () {
$('#tabs').tabs("refresh").tabs("option", "active", 0);
//Added to callback to convert navbar div into jQuery Mobile Navbar
$('#dashboard_navbar').navbar();
};
}
dvm = new DashboardViewModel();
ko.applyBindings(dvm);
});
这是页面的正文内容:
<body>
<div data-role="page" id="page-1">
<div data-role="header">
<h1>jQuery Mobile Tabs Test</h1>
</div>
<div data-role="content">
<div data-role="tabs" id="tabs">
<div data-role="navbar" id="dashboard_navbar">
<ul data-bind="template { foreach : tabs }">
<li><a data-bind="attr : { href: TabHref } , text: Title" data-ajax="false"></a>
</li>
</ul>
</div>
<div data-bind=" template { foreach :tabs, afterRender: refreshTabs}">
<div data-bind="attr : { id: TabID }" class="ui-body-d ui-content">
<h4 data-bind="text: Title" />
</div>
</div>
</div>
</div>
</div></body>
问题
但是,当您使用KnockoutJS加载一组绑定选项卡时,您只需在 foreach 绑定下提供一个 li 元素作为模板。 jQuery Mobile只看到1个元素,因此添加 ul-grid-solo 类,然后导航栏 li 元素最终被渲染为堆叠在一起而不是水平对齐。
解决方法
我到目前为止的解决方案是删除&#34;导航栏&#34; data-role ,而是使用KnockoutJS的afterRender回调,在插入所有绑定选项卡后将元素转换为导航栏。 (请参阅 DashboardViewModel 对象中的* refreshTab * s函数。)
这很有效,但不太理想,因为它强制ViewModel知道一些关于View的内容,这是MVVM禁忌。
问题
答案 0 :(得分:1)
使用淘汰赛和jQuery Mobile一段时间后,我可以确认他们根本不能一起玩。我们的团队有一个可重复使用的淘汰赛自定义绑定列表,仅用于使用jQuery mobile,因为它们非常痛苦。
您基本上可以将以下变通方法或您自己的变通方法包装到您用来代替foreach的自定义绑定中。或者订阅对导航栏项目数组的更改并在那里更新。
基于jsFiddle的解决方法,尝试重新创建导航栏,您还必须删除jQuery mobile放入元素的动态标记。尝试添加此内容(source):
navbar.find("*").andSelf().each(function(){
$(this).removeClass(function(i, cn){
var matches = cn.match (/ui-[\w\-]+/g) || [];
return (matches.join (' '));
});
if ($(this).attr("class") == "") {
$(this).removeAttr("class");
}
});