JohnSmith-UIを構築するためのシンプルで軽量なJavaScriptフレームワーク





現在まで、リッチクライアントアプリケーションを作成するためのJavaScriptライブラリが多数あります。 有名なKnockout、Angular.JS、Emberに加えて、他にも非常に多くのフレームワークがあり、それぞれが独自の特性を持っています-誰かがミニマリズムを促進し、誰かが-イデオロギーの純粋さとMVCの哲学への準拠。 この多様性により、ますます多くの新しいライブラリが定期的に登場しています。 habr - Warp9Matreshka.jsで言及された最後から。 この点で、私は自分のクラフトについてお話ししたいと思います。JohnSmith -UIを構築するためのシンプルで軽量なJavaScriptフレームワークです。








まず第一に、JohnSmithは学問的利益のために書かれたものではなく、致命的な欠陥を排除するものではないと言いたいと思います。 それどころか、JohnSmithは実際のプロジェクトで始まり、プロジェクトからプロジェクトに移行し、徐々にその形を改善し、変化させました。 そして今、それは本格的なオープンソースライブラリとして具体化しました。









JohnSmithの機能を示すために、次の機能を備えたシンプルなアプリケーションを作成します。



ユーザーが自分の名前を入力する入力フィールドがあります。 名前が入力されるとすぐに、メッセージHello、%username%が表示されます。



誰がすぐに結果を見たいのか:完成したユーザーGreeterは次のとおりです。







モデルを見る





ビューモデルを作成することから始めましょう。まず、「クラス」を作成します。



var GreeterViewModel = function(){ }
      
      







ビューモデルは通常、変更を外部から追跡できる外部の世界オブジェクトに「露出」します。 JohnSmithでは、これらのオブジェクトはバインド可能と呼ばれます。 ユーザー名を保存するフィールドを追加します。



 var GreeterViewModel = function(){ this.userName = js.bindableValue(); };
      
      







このフィールド( userName



)は、ビューでの双方向リンクに使用されます。 メッセージテキストを形成する別のフィールドを追加します。 このフィールドはuserName



に依存するため、 dependentValue



として説明します。



  var GreeterViewModel = function(){ this.userName = js.bindableValue(); this.greetMessage = js.dependentValue( this.userName, function(userNameValue){ if (userNameValue) { return "Hello, " + userNameValue + "!"; } return "Please, enter your name"; }); };
      
      







js.dependentValueは、JohnSmithで依存関係を手動で指定することを除いて、ノックアウトで計算されたものに似ています。 舞台裏では、自動追跡の魔法はありません。



Viewモデルの準備ができました。次に、Viewについて説明します。







表示する





クラスを作成することから始めましょう:



 var GreeterView = function(){ }
      
      







ビューは、マークアップと、このマークアップと外界との接続のロジックの組み合わせです。 マークアップはtemplate



フィールドで説明され、ロジックはinit



メソッドで説明されinit







 var GreeterView = function(){ this.template = "...  ..."; this.init = function(){ //    } };
      
      







このテスト例では、マークアップは非常に単純なので、テンプレートフィールドに直接書き込みます。



 var GreeterView = function(){ this.template = "<p>Enter your name: <input type='text'/></p>" + "<p class='message'></p>"; this.init = function(){ //     }; };
      
      







次に、 init



メソッドに進みinit



。 まず、JohnSmithは、各ビューが特定のビューモデルで機能することを暗示しているため、viewModelパラメーターを追加します。



 var GreeterView = function(){ this.template = "<p>Enter your name: <input type='text'/></p>" + "<p class='message'></p>"; this.init = function(viewModel){ // <--- //     }; };
      
      







さらに、ビューモデルのプロパティを、ビューが描画するマークアップに接続します。 JohnSmithは、この関連付けをjsコードで直接構成するための構文を提供します。 この場合、次のようになります。



 var GreeterView = function(){ this.template = "<p>Enter your name: <input type='text'/></p>" + "<p class='message'></p>"; this.init = function(viewModel){ this.bind(viewModel.userName).to("input"); // <--- this.bind(viewModel.greetMessage).to(".message"); // <--- }; };
      
      







これですべての準備が整い、ビューを描画するだけです(ページにid = 'greeter'の要素があることが理解されます):



 js.renderView(GreeterView, new GreeterViewModel()).to("#greeter");
      
      







これで、ガジェットが完成しました 。結果はここで見ることができます 。 この例は、フレームワークの基本的な哲学を示していますが、JohnSmithの機能についてさらに学習するために、いくつかの詳細を明確にします。







バインディング





JohnSmithのバインディングの基礎は、オブザーバブルオブジェクトです(ノックアウトなど)。 これらのオブジェクトは、次のいずれかの方法を使用して作成されます。







オブジェクトAとリスナーBの直接リンクは、次の形式のコードで構成されます。



 js.bind(A).to(B);
      
      







たとえば、次のように:



 var firstName = js.bindableValue(); //   js.bind(firstName).to(".firstName"); //   jQuery- firstName.setValue("John"); //   
      
      







ビュー内では、バインディングコードが少し変更されます。



 //    init   this.bind(viewModel.firstName).to(".firstName");
      
      







この場合、 .firstName



セレクターの検索は、このViewのマークアップ内でのみ機能し、ドキュメント全体では機能しません。 これにより、外部環境からビューを完全に独立させることができます。



構文js.bind(A).to(B)



使用すると、「宣言型」スタイルと命令型を組み合わせて、必要な場合にjQueryスタイルを使用できます。



 //      : js.bind(firstName).to(".firstName"); js.bind(firstName).to( function(newValue, oldValue){ // <--      //     jQuery  , // , / -    //   newValue/oldValue,  ,    .. });
      
      







通常の(観測不可能な)値をバインド可能なオブジェクトとして渡すと、インターフェイスとの1回限りの同期が発生します。 これにより、観察可能なビューモデルフィールドと「通常の」ビューモデルフィールドの両方を同じ方法で処理できます。



 var ViewModel = function(){ this.firstName = "John"; // static value this.lastName = js.bindableValue(); // observable value }; //... // somewhere in the View: this.bind(viewModel.firstName).to(".firstName"); // will sync only once this.bind(viewModel.lastName).to(".lastName"); // will sync on every change
      
      







複雑なオブジェクトを描画するには、子ビューを使用できます。



 var ViewModel = function(){ this.myAddress = js.bindableValue(); this.initState = function(){ this.myAddress.setValue({ country: 'Russia', city: js.bindableValue(); }); }; }; // ... this.bind(viewModel.myAddress).to(".address", AddressView); // ...
      
      











ビュー構成





JohnSmithのビューは、インターフェースを構築するための原子単位です。 各ビューは完全に独立しており、再利用の可能性を提供します。 アプリケーション全体のインターフェースは、「ツリー」( 複合パターン )を構築することにより、個別のビューで構成されます。 つまり、メインビューが1つあり、子ビューがあり、各子には独自のビューがあります。 構成は、いくつかの方法で実現されます。







複合ビューの小さなデモンストレーションとして、ファイルツリーは次のことを行います。





おわりに





結論として、JohnSmithの機能を示します。







githubのリポジトリ

それだけです、あなたの注意をありがとう、建設的な批判を待っています!



All Articles