フロート チャートを更新するためのカスタム バインディングを作成しようとしてきましたが、最初に読み込まれたときに動作するように見えますが、ナビゲートすると終了します。
シナリオは次のとおりです。1つのページ(これはjQuery Mobileにあります)にリストビューがあり、グラフのサムネイルがほとんどありません。グラフの隣には、同じビューモデルのプロパティにバインドされたスライダーがあり、グラフポイントを再計算されます。リスト項目の 1 つをクリックすると、グラフのより大きなバージョンを表示する別のページに移動し、テキスト ボックスに入力して値を変更できます (後で、グラフを直接クリックできるようになります)。 . バインディングは次のようになります。
ko.bindingHandlers["plot"] = {
init: function (element, valueAccessor, allBindingsAccessor) {
var qe = $(element);
var page = qe.closest("div[data-role='page']");
page.bind("pageshow", function () {
ko.bindingHandlers["plot"].update(element, valueAccessor);
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var qe = $(element);
var page = qe.closest("div[data-role='page']");
var curr = $.mobile.activePage;
var val = ko.utils.unwrapObservable(valueAccessor());
var data = val.plotData();
if(data && page.prop("id") == curr.prop("id")) {
var marker = val.markerData();
var opt = val.chartOptions();
opt.yaxis.show = opt.xaxis.show = !qe.hasClass("graphThumb");
marker.points.radius = opt.yaxis.show ? 5 : 3.5;
$.plot(qe, [
data,
marker
], opt);
}
}
};
ハンドラーはinit
、非表示の に描画するときに flot が正しく機能しないため、ページ ショーにグラフを描画するように設定しますdiv
。更新では、現在表示されているページがバインディングのあるページと同じかどうかがチェックされ、必要に応じてグラフが再描画されます。
リスト ビューのグラフは、メソッドによってすぐに描画され、update
正しく機能します。ただし、最初は非表示のページの場合、グラフを描画する関数が起動し、グラフは描画されますが、更新は機能しなくなります。さらに悪いことに、最初のページに戻ると、pageshow
イベントにバインドされた関数が起動し、グラフが再描画されますが、更新も停止しています。
ビュー モデルは次のようになります。
var viewModel = (function () {
this.current = ko.observable(0);
this.plotData = ko.computed(function () {
var points = [];
// a bunch of calculations that depend on the value of current of this and other viewModels in a collection
return points;
}
}
計算結果にブレーク ポイントを設定するplotData
と、正しく更新されていることがわかります。これらの更新がバインディング ハンドラーをトリガーしないだけです。
HTML バインディングは次のようになります。
<!-- the first, visible page -->
<div data-role="page" id="index">
<ul data-role="listview" data-bind="foreach: factors">
<li data-bind="attr: {id: listId}">
<a data-bind="attr: {href: idLink}">
<div class="graphThumb" data-bind="plot: $data"></div>
</a>
</li>
</ul>
</div>
<!-- hidden details pages -->
<!-- ko foreach: factors -->
<div data-role="page" data-bind="attr: { id: id }">
<div class="graphPlaceHolder" data-bind="plot: $data"></div>
</div>
<!-- /ko -->
更新:イベント ハンドラーで を呼び出すだけで問題は解決しないことに気付いたので、バインディングを少し変更しupdate
ました。pageshow
それを行うと、バインディングの依存関係であるノックアウトが更新されないようです。
更新:別の更新、変数への割り当てval.plotData()
が機能せず、if
ステートメントに含めることもできませんでした。current
ただし、親ビューモデルの値と別のプロパティに依存する別の計算されたオブザーバブルがあり、それらを取得してif
ステートメントに追加することができます。ただし、私の解決策は、おそらく一般的に役立つようにすることです。簡単に言うと、ノックアウトは更新ごとにバインディングの依存関係を再評価するため、条件付きロジックに関係なく重要なものを評価していることを確認する必要があります。そうしないと、更新が停止します。