我有以下标记:
<div id="metro-hub">
<h1 id="hub-title" data-bind="text: hubTitle" class="hub-title">@Model.HubTitle</h1>
<div id="hubWrapper" data-root-url="/Root" data-bind="html: currentHub"></div>
</div>
我正在使用KnockoutJS将viewModel
JavaScript对象绑定到视图。我还创建了一个自定义绑定来将导航连接到服务器上的站点地图。以下是我到目前为止所获得的一些片段:
var MetroPageViewModel = function () {
var self = this;
self.currentHub = ko.observable();
self.viewPortData = ko.observable();
self.hubTitle = ko.observable();
self.renderHub = function (rootUrl) {
console.log(rootUrl);
$.ajax({
url: '/Base/NewHub',
type: 'get',
data: {
url: rootUrl
},
success: function (data) {
if (data) {
var wrappedData = $(data);
var newHubContent = wrappedData.find('ul');
var title = wrappedData.find('input.metro-hub-title').val();
self.hubTitle(title);
self.currentHub(newHubContent); //THIS IS THE LINE THAT DOES NOT WORK
}
}
});
};
self.initialize = function () {
var url = $('#hubWrapper').data('root-url');
self.renderHub(url);
};
};
$(function () {
var viewModel = new MetroPageViewModel();
ko.applyBindings(viewModel);
viewModel.initialize();
});
这是使用Sammy.js库根据url哈希进行路由的自定义绑定:
ko.bindingHandlers.metroHub = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var menuItems = $(element).find('li');
Sammy(function () {
var $this = this;
menuItems.each(function (index, elem) {
$this.get('#/' + $(elem).data('link-name'), function () {
var numChildren = $(elem).data('num-children');
if (numChildren > 0) {
var rootUrl = (elem).data('source-url');
viewModel.renderHub(rootUrl);
} else {
var dataSource = $(elem).data('source-url');
$.ajax({
url: dataSource,
type: 'get',
success: function (data) {
if (data) {
viewModel.viewPortData(data);
}
}
});
}
});
});
var firstItem = menuItems[0];
var itemRoute = '#/' + $(firstItem).data('link-name');
$this.get('', function () { this.app.runRoute('get', itemRoute) });
}).run();
}
};
从服务器返回的数据如下:
<div><ul class="metro-menu" data-bind="metroHub: true"><li data-link-name="Home" data-num-children="0" data-source-url="/Navigation/Item1"><a href="#/Home">Home</a></li><li data-link-name="Products" data-num-children="2" data-source-url="/Navigation/Item2"><a href="#/Products">Products</a></li><li data-link-name="Services" data-num-children="0" data-source-url="/Navigation/Item3"><a href="#/Services">Services</a></li></ul>
<input class="metro-hub-title" type="hidden" value="this is a hub title"></input>
<input class="hasParentNode" type="hidden" value="False"></input>
</div>
更新
现在的问题是,一旦update
方法中的AJAX回调返回,就不会触发自定义绑定renderHub()
回调。我是否需要调用某种方法强制绑定或其他什么?
有什么想法吗?
答案 0 :(得分:0)
也许您应该将更新绑定放在父容器上,因为该控件正在更新。
我认为更新未触发是因为应该响应更新的旧div完全被新的html取代。
您可以使用与更新相同的代码在绑定中创建init函数,以快速检查是否正确。