
こんにちは、ハブラフチャン。 今日は、プロキシとその他のECMAScript 2015の便利な機能を使用して、一方向のデータバインディング機能を備えたデータウェアハウスを作成します。
プロキシとは何ですか?
簡単に言えば、プロキシはオブジェクト
ラッパーであり 、これを使用すると、作成元のオブジェクトへの呼び出しをインターセプトできます。 呼び出しをインターセプトするために
、トラップの武器で武装したプロキシには、いくつかのインターセプター機能があります。 フックリストとすべてのプロキシメソッドの詳細については、
こちらをご覧ください 。
どうする?
プロキシを使用して、変更追跡機能を備えたオブジェクトのリポジトリを実装します。 ある種の故人のウーといくつかの追加の特典。
さあ行こう...
仕事用
ストレージは、ストレージファクトリクラスのインスタンスです。
"use strict"; class OS {
将来発生するすべては、OSクラス内で発生します。
リポジトリには、次のデータ構造が必要です。
{ : { : } :{ :{ :{ id : } } } }
したがって、必要なすべての機能を実装するために、コンストラクターでデータストレージのオブジェクトを定義します。
class OS { constructor() { this.storage = new Map();
Mapおよび
Setクラスの説明は意図的に省略します。 それらについて詳しく知りたい場合は、
こちらと
こちらをご覧ください 。
serviceFieldフィールド
は 、オーバーヘッドを上書きまたは反復する可能性を排除するために必要ですが、それについては後で詳しく説明します。
次のステップは、新しいオブジェクトをリポジトリに追加する組織です。
オブジェクトを持つ:
let object = {key1: ”data”, key2: 1}
オブジェクトをストアに追加する次のメソッドを実装します。
let wrapper = ObserveStorage.add(key, object);
最初のパラメータは、オブジェクトがリポジトリに記録されるキーを決定し、2番目はオブジェクト自体です。 出力では、ベースオブジェクトのプロキシラッパーを取得します。
事前に、すべてのユーザーがリポジトリからオブジェクトを取得する機能に関心があるわけではなく、すべてのキーを監視することは必ずしも便利ではないため、このエントリも有効です。
let wrapper = ObserveStorage.add(object);
異なるキーとIDを使用するため、それらを生成する簡単なメソッドを作成します。
static __getId() { return (`${Math.random().toFixed(10).toString().replace("0.", "")}${Date.now()}`) }
インターフェイスを定義し、さまざまな種類の識別子を生成するツールが用意できたので、メソッドの開発を開始できます。
add(...arg) {
getProxyメソッドは
未解決のままでしたが、私はあなたのことは知りませんが、秘密は我慢できません。 したがって、行こう:
イベントを生成するときに注意することが重要です
self.fire(key, { type: oldValue ? "change" : "add", property: field, oldValue: oldValue, value: value, object: self.get(key) });
ターゲットは
targetではなく、ラッパーです。 これは、
コールバック内のオブジェクトを変更することにより、ユーザーが追跡されていない変更を行わないようにするために必要です。 最初に、オブジェクトのコピーをそこに転送しましたが、実際にはあまり良くありません。 上記のブロックでは、.getや.fiteなどのメソッドが強調表示されているため、順番にそれらについて説明しましょう。
.getメソッドは、リポジトリ内のオブジェクトを単にチェックし、それを返します。
get(key) { if(this.storage.has(key)) return this.storage.get(key); else{ console.warn(`Element ${key} is not exist`); return undefined; } }
.fireメソッドについて説明する前に、イベントサブスクリプションについて言及する価値があります。 サブスクリプションには次のインターフェイスが使用されます。
wrapper.on(callback, property = "*");
どこで
property = "*"
はデフォルト値であり、このオブジェクトのすべてのフィールドへのサブスクリプションを示します。
例:
wrapper.on(event => console.log(JSON.stringify(event)), "value"); wrapper.data = "test";
リポジトリにオブジェクトを記録するときに、このメソッドをオブジェクトに統合します(上記を参照)。 メソッド自体は次の関数です。
on(key, callback, property = "*") {
.onメソッドの最初のパラメーターに特に注意を払います。 注意深いのは、1つまたは2つのパラメーターが渡されることですが、メソッドは3つを期待し、そのうちの1つがキーであることに気付きました。
そして、最も注意深い人は、リポジトリ、つまり次の行でオブジェクトを初期化するときにメソッドのキーをロックしたことを覚えています。
object.on = (...arg)=> self.on(key, ...arg);
サブスクリプションを解除するには、サブスクリプション中に受け取ったサブスクリプションIDを使用する必要があります。
wrapper.un(subscriptionId);
機能説明:
un(key, subscriptionId) {
さまざまな種類の操作にidを使用するのが好きです。これにより、かなり透明な形式でユーザーアクションを明確に識別できるからです。
それで、ラッパーにかかっているすべてのコールバックをプルする.fireメソッドを呼び出すことになりました。
fire(key, event) {
fireListenersメソッドは透過的であり、説明は不要です。
fireListeners(event, listeners) { listeners.forEach((listener)=> { setTimeout(()=> listener(event), 0); }) }
まとめると
したがって、オブジェクトの変更をサブスクライブする機会を得ながら、わずか150行のコードでデータウェアハウスを記述しました。 Ooの遺産に従い、現在、ネストされたオブジェクトをラップせず、配列を処理しませんが、必要に応じてこれらすべてを実装できます。
完全なコードは
こちらにあります 。
あなたと
一緒に、
罪人 。
あなたに良い、地球人。