- はじめに
- 継承
- MK.Object
- MK.Array
- Matreshka.js v0.1
- Matreshka.js v0.2
- TodoMVCの実装
(以前の記事はすべて現在の状態に更新されました)
リポジトリ
サイト(ドキュメントもあります)
みなさんこんにちは。 マトリョーシカに関する一連の記事が最後に公開されてから5か月が経過しました。 それ以来、少数のエラーが修正され、コメントの影響下でプロジェクトがShoojuのスポンサーを見つけ、ロゴと通常のブートストラップ以外のWebサイトを受け取ったなど、いくつかの便利な機能が登場しました。
マトリョーシカは、データの重要性が外観を支配する汎用フレームワークであり、データが更新されるとインターフェイスが自動的に更新されることを思い出させてください。
Matryoshkaを使用すると、データとプレゼンテーションのさらなる同期を心配することなく、データとプレゼンテーション要素(オブジェクトプロパティや入力フィールドの値など)を簡単に関連付けることができます。 たとえば、最も単純なバインディングは次のようになります。
インスタンスを作成します。
xプロパティを
要素に
。
データを変更する
プロパティxに異なる値を割り当てた後、それに応じて要素の状態が変化します。
ライブ例をご覧ください
入れ子人形のもう1つの重要な機能は、イベント(カスタムイベントを含む)です。 たとえば、マトリョーシカはプロパティの値の変化をキャッチできます。
コードは
を出力します。
これらおよびその他の機能の詳細については、上記のリンクを参照してください。
<select class="my-select"> <option>1</option> <option>2</option> <option>3</option> </select>
インスタンスを作成します。
var mk = new Matreshka();
xプロパティを
.my-select
要素に
.my-select
。
mk.bindElement( 'x', '.my-select' );
データを変更する
mk.x = 2;
プロパティxに異なる値を割り当てた後、それに応じて要素の状態が変化します。
ライブ例をご覧ください
入れ子人形のもう1つの重要な機能は、イベント(カスタムイベントを含む)です。 たとえば、マトリョーシカはプロパティの値の変化をキャッチできます。
mk.on( 'change:x', function( evt ) { alert( 'x ' + evt.value ); });
コードは
"x "
を出力します。
mk.x = '';
これらおよびその他の機能の詳細については、上記のリンクを参照してください。
記事のデザインについて少し
jsdoc構文を使用してメソッドとプロパティを示します。特に、ラティス(#)は、たとえば
は、
のインスタンスである
メソッドについて説明していることを意味します。
MK#addDependence
は、
MK#addDependence
のインスタンスである
addDependence
メソッドについて説明していることを意味します。
最もおいしい
依存関係( MK#addDependenceメソッド )
この最もクールな方法を使用すると、一部のデータが他のデータに依存することを確認できます。 最初の引数は依存プロパティのキー、2番目はプロパティが依存するキーの配列(またはスペースで列挙されたキーを持つ文字列)、3番目はプロパティの新しい値を返すハンドラー関数です。 これは、プロパティを取得するたびにgetterが呼び出され、プロパティが依存するデータを変更するときに、
addDependence
がプロパティの値を事前に計算するという違いがあるゲッターの一種の置換です。 比較的重い計算はコードのパフォーマンスに大きな影響を与える可能性があるため、ゲッターを慎重に使用する必要があります。 リソースの消費という観点から見ると、「依存関係」はデータ変更イベントの通常の処理と違いはなく、実際、それらに対する構文上の砂糖です。 さらに、このメソッドは自己文書化コードに向けたもう1つのステップです。
プロパティー
f
常にプロパティー
a, b, c, d, e
の合計になる必要があるとしましょう。
これは、純粋なイベントに基づいたコードのようです。
this.on( 'change:a change:b change:c change:d change:e', function() { this.f = this.a + this.b + this.c + this.d + this.e; });
それをこれと比較してください:
this.addDependence( 'f', 'abcd e', function() { return this.a + this.b + this.c + this.d + this.e; });
またはこれでも:
this.addDependence( 'f', 'abcd e', function( a, b, c, d, e ) { return a + b + c + d + e; });
まず 、ジェスチャを少なくする必要があります(
'change:'
をヒープする必要はありません)
第二に 、メソッドと引数の名前により、対応するコード行が作成される理由を明確に理解します。 人間の言語に翻訳すると、最初の方法は「
a, b, c, d, e
のプロパティを変更するとき
a, b, c, d, e
何かをするとき」、2番目の方法は「プロパティ
f
プロパティ
a, b, c, d, e
への依存性を追加する」 「。 違いを感じますか?
第三に 、他のプロパティが依存するプロパティの1つが
silent
フラグで変更された場合、最初のオプションは機能しません。
たとえば、境界線を計算するタスクがあります。
オプション1、イベント時:
this.on( 'change:a change:b', function() { this.p = ( this.a + this.b ) * 2; });
依存関係を使用するオプション2:
// 2 this.addDependence( 'p', 'a b', function() { return ( this.a + this.b ) * 2; });
今、私たちが呼び出す場合:
this.set({ a: 2, b: 3 }, { silent: true });
...その後、最初のバリアントではp
は変化せず、2番目では変化します。
p
変更でイベントハンドラーをハングさせ、
p
が
silent
フラグの変更に依存するプロパティの1つをハングさせた場合、予想どおり、変更ハンドラー
p
は呼び出されないことに注意してください。
this.on( 'change:p', function() { /* ... */ } ); this.set( 'a', 12, { silent: true }); // "p" ""
次のバージョンでは、他のクラスにあるデータへのプロパティの依存関係を追加する予定です(データが外観を支配するアプリケーションの一般的なタスク)。 これは既に実装されていますが、言語構文の制限により文書化されていません。 他のクラスへの依存関係は次のようになります。
this.addDependence( 'a', [ instance1, 'bc d', instance2, 'ef g', this, 'hij' ], function() { /* ... */ });
2番目の引数の奇数の配列要素がインスタンスである場合、偶数の要素はキーのリストです。 具体的に見えますが、他のオプションがあれば嬉しいです。
例のあるページで、メソッドliveを見ることができます。
Rendolのコメントに関して:マッピングは依存関係を使用して実装できます。
メディエーター(仲介者)
MKメソッド#setMediator
多くの場合、データの検証と変換のタスクが含まれます。 クラスにプロパティがあるとします。プロパティは常に文字列であり、他には何もありません。 標準ツールを使用してこの問題を解決してみましょう。
// - this.on( 'change:a', function() { if( typeof this.a !== 'string' ) { this.a = String( this.a ); } }); // - 1 this.on( 'change:a', function() { if( typeof this.a === 'string' ) { /* ... */ } }); // - 2 this.on( 'change:a change:b', function() { if( typeof this.a === 'string' ) { /* ... */ } }); // this.a = 123;
ここで何が起こっているのか理解していますか? 最初のハンドラーは
a
を文字列に変換
a
、最後の2つのハンドラーは
a
文字列かどうかを強制的にチェック
a
ます。コンバーターハンドラーはすべてのハンドラー(自身を含む)を再び開始するからです。
beforechange:%%
event
beforechange:%%
ような解決策を求めて
beforechange:%%
、フレームワークに新しい概念「中間体」を導入することが決定されました。
メディエーター(またはメディエーター)は、このプロパティーの変更に関連するイベントがトリガーされる前に、プロパティーの値を変更します。
MK#setMediator
の構文は単純です。最初の引数はメディエーターを設定するキー、2番目の引数はプロパティの新しい値を返す関数です。 代替構文:クラスで複数のメディエーターを一度にハングアップする場合、メディエーターキーオブジェクトがケースのメソッドに渡されます。
たとえば、プロパティ
a
は常に文字列で、プロパティ
b
は常に整数(または
NaN
)でなければなりません
this.setMediator( 'a', function( value ) { return String( value ); }); this.setMediator( 'b', function( value ) { return parseInt( value ); });
そして、JavaScriptをよく知っている人のために:
this.setMediator( 'a', String ); this.setMediator( 'b', parseInt );
メディエーターは、そのような単純な可能性に限定されません。 計算の実行を禁止するものはありませんが、アプリケーションのパフォーマンスを損なわないように注意してください。
この方法は、サーバーが特定のタイプの値を受け入れる場合を含め、非常に便利でクールです。 メディエーターは1つだけです。 同じプロパティでの次の
MK#setMediator
は、古いピックをブロックします。 「中間」を削除するために、関数の代わりに
null
を渡すことができます。
例のあるページから実際の例を見てみましょう 。
mk.setMediator({ percentageValue: function( v ) { return v > 100 ? 100 : v < 0 ? 0 : v; }, stringValue: String, integerValue: parseInt });
3つのプロパティにピックを設定しました。 1つ目はパーセントプロパティです:プロパティの値は0から100までで、この範囲の境界を超えるものは自動的に有効な値に変換されます(0未満の場合、値は0になり、100を超える場合、値は100になります)。 2番目の値は文字列です。プロパティは常に文字列でなければなりません。 3番目は常に整数(または
NaN
)でなければなりません。 アイデアを開発するには、常に真または偽のプロパティを作成し、常に何らかのクラスのインスタンスになるプロパティを作成します...
MK.Arrayメソッド#setItemMediator
別の種類のメディエーターがあります:配列要素のメディエーターです。 このようなメディエーターをインストールすると、追加された各要素が希望どおりに変換されます。 ドキュメントの例をご覧ください。
var mkArray = new MK.Array( 1, 2, 3, 4, 5 ); mkArray.setItemMediator( function( value ) { return String( value ); }); mkArray.push( 6, 7 ); mkArray.unshift( true, {} );
console.log( mkArray.toJSON() ); // [ "true", "[object Object]", "1", "2", "3", "4", "5", "6", "7" ]
これにより、型付き配列、つまり文字列の配列が作成されます。 はい、もちろん、そのような型付き配列は、組み込み型付き配列とパフォーマンスがさらに異なります。 しかし、データを検証および変換する機能には限界がありません。
配列要素のメディエーターがクラス全体で唯一のものであることを忘れないでください。 また、メディエータを
null
設定することで削除でき
null
。
mkArray.setItemMediator( null );
ところで、上記の例は上級プログラマ向けに修正できます。
mkArray.setItemMediator( String );
かっこいい
「多数のアプリケーションによる」
記事の最初のシリーズの発行後、habrayuzersはマトリョーシカのいくつかの機能を批判しました。 批判は十分に根拠があり、物議を醸す問題を検討して修正することが決定されました。 それらのいくつかを次に示します。
1. MK.Array#popおよびMK.Array#shiftは、「self」ではなく、削除されたアイテムを返します。 Starfall : 記事へのコメント 、 winbackgo : 記事へのコメント
2.
input[type="text"]
および
'keyup'
デフォルトのバインダーは、
'keyup'
だけでなく
'paste'
イベントをリッスンするようになりました。 safron : 記事へのコメント
3.
input[type="checkbox"]
および
input[type="radio"]
のデフォルトのバインダーは、
'keyup'
イベントをリッスンするようになりました。 これは、これらの要素にデータをバインドするときにキーボードからこれらの要素を操作できることを意味します(同じコメント)。
バラライカ
さらに、
jQuery
への強い依存関係を削除することが決定されました。 私の意見では、
jQuery
は素晴らしいライブラリですが、新しいブラウザーでは関連性を失います。 現在、ページに
jQuery
ない場合、「Balalaika」と呼ばれるミニライブラリに置き換えられます(注:そうでない場合のみ
jQuery
接続されている場合、
jQuery
は引き続き使用されます)。
balalaikaは
Array.prototype
継承するため、開発者は配列に含まれるすべてのメソッドに加えて、クラス(
addClass
、
removeClass
、
hasClass
)、イベント(
on
、
off
)、HTML解析(
parseHTML
)などを
parseHTML
jQuery
互換メソッドを使用できます。
Balalaikaを直接使用するには、グローバル変数$ bが使用されます。
$b( 'div' ).forEach( function(){ /* ... */ } ); $b( '.blah-blah', context ).is( 'div' ); $b( 'input[type="text"]' ).on( 'keydown', handler );
(バラライカに関する別の投稿を書く予定です)
banzalik : 願いを込めてコメントする
jMas : 別のコメント
その他の革新
MK#選択方法
this
バインドされたセレクター内のセレクターに一致する最初の要素を選択し
this
(キー
"__this__"
、以前の記事を参照)。 このメソッドは、要素のコレクションではなく、個々の要素での作業を簡素化するために作成されました。
this.select( '.blah-blah' );
MK#selectAllメソッド
this
へのバインド内でセレクターに一致するすべての要素を選択します。
$
(ドル記号)メソッドと同じです。
MK#selectAll
、メソッドのセットを完了するため
MK#selectAll
作成されました。「select」メソッド(
MK#select
)がある場合、「select all」メソッドが必要です。
this.selectAll( '.blah-blah' ); // , this.$( '.blah-blah' );
MK.Array#pullメソッド
指定されたインデックスを持つアイテムを削除して返します。
var x = this.pull( 3 );
これは、
splice
上の構文糖です。
var x = this.splice( 3, 1 )[ 0 ];
プロパティisMK 、 isMKArrayおよびisMKObject
対応するクラスのインスタンスで常に
true
であるプロパティ。
var mkObject = new MK.Object(); alert( mkObject.isMK && mkObject.isMKObject ); // true
修正
さらに、いくつかのバグが修正されました。 修正のリストは次のとおりです。
- 引数としてMK.Object#addJSONKeysおよびMK.Object#removeJSONKeysメソッドが
undefined
渡された(または何も渡されなかった)場合は何もしません。 - MK.Object#addJSONKeys 、 MK.Object#removeJSONKeys 、 MK#removeメソッドで数値を使用できます
- MK#onceメソッドを修正
名前が変更されたメソッドとプロパティ
semver.orgの推奨事項に従って、廃止されたメソッドとプロパティはリリース1.0まで削除されませんが、警告と新しいメソッドを使用する要求はコンソールに表示されます。
- MK.elementProcessors-> MK。 defaultBinders
- MK#el-> MK# バウンド
- MK#$ el- > MK# boundAll
- MK.htmlp-> MK。 バインダ.innerHTML()
- MK.classp()-> MK。 バインダ。クラス名()
スマートアレイ
MK.Array
プラグインは
MK.Array
で言及されて
MK.DOMArray
、
MK.Array
に関する記事で言及されてい
MK.Array
。 つまり、「注目を集める」GIFが反映する機能は、そのままで機能していました。
MK.DOMArray
プラグインは、配列が変更(追加、削除、並べ替えなど)すると自動的にDOMを変更することを思い出させてください。
マトリョーシカのウェブサイトの例をご覧ください 。 スマートアレイの詳細な説明は、少し後で計画されます。
ロードマップ
- 置換可能な
Model
プロパティを実装します(これはBackbone
のmodel
似ています)。 この機能は、配列要素のメディエーター上の構文糖衣です。 - 遅延初期化。 現在、継承するときは、常に
initMK
メソッドを呼び出す必要があります。 コーシャではありません。 - イベントエンジンを書き換えます。 おそらく、DOM
EventTarget
インターフェースがEventTarget
となるでしょう。 -
MK#addDependence
を更新して、他のクラスインスタンスへの依存関係を作成します(上記を参照)。 - ミニファイヤのコードを最適化します。
- サイト上の正しいテキスト。 ご覧のとおり、サイトは英語であり、テキストに誤りがあります。 エラーがあるテキストを選択した後、Ctrl + Enterの組み合わせを使用して、エラーを修正することができます(要求プールを作成しないように)。 とても感謝します。
バージョン1.0(約1年後に予定)では、最初に廃止されたメソッドを削除し、次に8番目のドンキーのサポートを削除する予定です。 IE8をサポートする人がいなければ、すべてのインターネットの子猫は幸せになります。
結論として
プロジェクトの周りの明らかな沈黙にもかかわらず、マトリョーシカは開発中です。 すべての機能は徹底的にテストされているだけでなく、ライブアプリケーションでも動作します。
Matryoshkaのもう1つの目標は、フレームワークを使用する開発者を「データの神」にし、インターフェイスを気にせずに、モデルで何が起こっているかを完全に制御することです。 たとえば、オブジェクトと配列のツリーにデータ変更イベントのポップアップイベントを実装する予定で、これは非常にクールです。 さらに-もっと...
アクセサ(ゲッターとセッター)に基づいたMatryoshkaコアによって提供されるスペースは、プログラマーの創造性のための最も広い分野を提供します。 同意し、仲介者と依存関係のアイデアは表面にあります。 入力では、
value
プロパティは常に文字列であるため、そこに配置しないように、
valueAsNumber
プロパティ
valueAsNumber
常に文字列値に依存する数値です...
投稿を最後まで読んだ(またはスクロールしてくれて)ありがとう。 すべての善の光線。