私は次のマークアップを持っています:
<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()
返されると、カスタムバインディングコールバックがトリガーされないことです。バインディングなどを強制するために何らかのメソッドを呼び出す必要がありますか?
何かご意見は?