免責事項: pager.js については何も知りませんが、一般的なノックアウトの経験が役立つことを願っています。
例を見ると、page
バインディングは URL の初期値を使用してオブザーバブルを作成しているようです。私の最初の本能は、このバインディングを拡張し、これらの各値へのサブスクリプションが URL を更新することを確認することです。
このバインディングに名前を付けましょうtwoway-page
:
ko.bindingHandlers["twoway-page"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Call pager.js' page binding
ko.bindingHandlers.page.init(element, valueAccessor, allBindings, viewModel, bindingContext);
// ...
}
}
そして、例のバインディングでそれを呼び出します:
<div data-bind="twoway-page: {
id: 'start',
params: ['first','last']
}">
を呼び出した後、ページ バインディングはビューモデルを拡張し、配列page.init
で定義されたオブザーバブルをオブジェクトに追加します。これは、これらのオブザーバブルの変更をサブスクライブできることを意味します。params
viewModel
次の課題は、正しいハッシュを計算することです。page-href
バインディングがそのhref
属性を計算する方法を調べました。andプロパティpager.page.path()
を持つオブジェクトで使用されていることがわかりました。例えば:path
params
var hash = pager.page.path({
path: "user",
params: {
"first": "John",
"last": "Doe"
}
});
計算されたオブザーバブルで同様のオブジェクトを構築しようとしました。
// ...
var options = valueAccessor();
var pathObj = ko.computed(function() {
var result = {
path: options.id,
params: {}
};
options.params.forEach(function(param) {
result.params[param] = viewModel[param]();
});
return result;
}).extend({ rateLimit: { timeout: 200, method: "notifyWhenChangesStop" } });
pager.js メソッドを介してハッシュを更新する「クリーンな」方法を見つけることができませんでしたが、内部的に pagerjs がlocation.hash = "newhash"
値を設定するために使用していることに気付きました (history/html5 の代替手段もあるようですが...) . とにかく、オブザーバブルをサブスクライブしてハッシュを更新できます。
// ...
pathObj.subscribe(function(newValue) {
location.hash = pager.page.path(newValue);
});
text
ここで、例のバインディングの代わりにバインディングを使用textInput
して、値を更新できるようにします。
<div>
<span>First name:</span>
<input type="text" data-bind="textInput: first">
</div>
まとめとして、私の最善の推測は
- 既存の pager.js バインディングを拡張する
- URL で更新する必要があるすべてのオブザーバブルへのサブスクリプションを作成します
- 値が変更されたときにハッシュを自動的に更新します。
rateLimit
更新の過負荷を防ぐために拡張機能を使用する
ロケーション ハッシュを使って何かを行うのは、フィドルで表示するのが少し難しいため、概念実証の gif を記録しました。
完全なカスタム バインディング コードは次のとおりです。
ko.bindingHandlers["twoway-page"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
ko.bindingHandlers.page.init(element, valueAccessor, allBindings, viewModel, bindingContext)
var options = valueAccessor();
var pathObj = ko.computed(function() {
var result = {
path: options.id,
params: {}
};
options.params.forEach(function(param) {
result.params[param] = viewModel[param]();
});
return result;
}).extend({ rateLimit: { timeout: 200, method: "notifyWhenChangesStop" } });
pathObj.subscribe(function(newValue) {
location.hash = pager.page.path(newValue);
})
return { controlsDescendantBindings: true }
}
};