Internet Spaceships のフィッティングに必要な計算を実行するライブラリを TypeScript で開発しました。ライブラリ自体は今のところ素晴らしいものになっていますが、インタラクティブな HTML UI に接続するのに苦労しています。今のところ Knockout で動作するようにしようとしていますが、この特定のタスクが簡単になる場合は、別のフレームワークを使用することにオープンです。
私が抱えている特定の問題は、プレーンな JS 関数の結果にバインドする方法です。最初のページは初期の適切な値で素晴らしく表示されますが、ビジネス オブジェクトの別の関連フィールドを変更すると、バインドされた値が更新されません。
これを読むと、これを修正する方法は次のいずれかのようです。
- ライブラリをそのままにして、依存するオブザーバブルが値の計算の一部として呼び出されるように、Knockout オブザーバブルを使用してビューモデルを開発します。
- ライブラリをやり直して、Knockout オブザーバブルをコアに含めます。
- 依存関係マトリックスを手動で導入する方法を見つけます (基本的に、この情報を Knockout に強制的にフィードします)。
#2 は本質的に不可逆的な決定であるように思われるため、実行しないことを本当に望んでおり、ライブラリをプレーンな JS (TS) として保持し、node.js やその他のシナリオで役立つ可能性があるため、UI から分離したいと考えています。ノックアウトはあまり適切ではありません (間違っていたら訂正してください)。
#3 の実行方法に関する情報は見つかりませんでしたが、適切なキーワードが得られなかった可能性があります。
というわけで、#1 は、UI が何かを更新したいときに呼び出さなければならない、偽のオブザーバブルと手動の更新メソッドを導入することで、Knockout を偽造するというあまり巧妙ではないアイデアを思いつきました。#1はまた、基本的にライブラリを2回作成する必要があります.1回は計算用、もう1回はプレゼンテーション用です。
ここで非常に単純な#1をモックアップしました:http://jsfiddle.net/wxks8/6/
例:
var myViewModel = {
ship: ko.observable(theShip),
seq: ko.observable(1)
};
myViewModel.refreshAll = function () {
myViewModel.seq(this.seq() + 1);
};
myViewModel.shipStructureHP = ko.computed(function () { var x = this.refreshAll(); return theShip.structureHP(); }, myViewModel);
var myCode = {};
myCode.setSkills = function (theSkillLevel) {
myViewModel.ship().pilot.skills.SetAllSkills(theSkillLevel);
myViewModel.refreshAll();
}
上記の例では、shipStructureHP() ko.computed 関数は、Knockout が "Seq" オブザーバブルを使用することを認識している RefreshAll メソッドを呼び出します。これは、ノックアウトが shipStructureHP() を Seq に依存するものとして記録することを意味します。したがって、Seq をインクリメントするたびに、shipStructureHP() にバインドされた要素を再レンダリングする必要があります。
これは大きなハックのように感じられるので、ここで正しいことをしているとは思えません (refresh が複数回呼び出されるバグは気にしないでください)。
レガシー ブラウザーをサポートする必要はないので、関数を ES5 プロパティに変換することが役立つ場合は、それを行うことができます。ビジネス ライブラリをプレーンな JS のままにして、Knockout (または同様のライブラリ) でこのデータバインディングを行う方法についての提案をお待ちしています。私の偽の依存関係のアイデアよりもこれを行うためのより良い方法はありますか? バインド可能なビューモデルを取得するためだけに、UI でビジネス ライブラリの大部分を複製する必要がないものが望ましいです。
ありがとう。