KnockoutJS-クイックガイド

KnockoutJSは基本的に、開発者がリッチでレスポンシブなWebサイトを構築するのに役立つMVVMパターンに基づいてJavaScriptで記述されたライブラリです。モデルは、アプリケーションのモデル(保存されたデータ)、ビュー(UI)、およびビューモデル(モデルのJavaScript表現)を分離します。

KnockoutJSは、2010年7月5日にマイクロソフトの従業員であるSteve Sandersonによって開発され、オープンソースプロジェクトとして維持されています。KOはKnockoutJSの略語です。KOは、IE 6以降、Firefox 3.5以降、Chrome、Opera、Safari(デスクトップ/モバイル)のすべての主流ブラウザをサポートしています。

KnockoutJSの機能

これがKnockoutJSの最も顕著な機能のいくつかのリストです-

  • Declarative Binding− HTML DOM要素は、非常に単純な構文を使用して、data-bind属性を介してモデルに接続されます。この機能を使用すると、応答性を簡単に実現できます。

  • Automatic UI Refresh−モデルデータを表示するために行われた変更は、UIに自動的に反映され、その逆も同様です。余分なコードを書く必要はありません。

  • Dependency Tracking−KO属性とKOライブラリ関数/コンポーネントの関係は透過的です。KO属性のデータ変更を自動的に追跡し、それぞれの影響を受ける領域を更新します。

  • Templating −テンプレートは、ビューモデルデータの関数として、複雑なUI構造を構築するためのシンプルで便利な方法です(ブロックを繰り返したりネストしたりする可能性があります)。

  • Extensible −カスタム動作を非常に簡単に拡張します。

KnockoutJSを使用する理由

  • KnockoutJSライブラリは、複雑なデータ駆動型インターフェイスを処理するための簡単でクリーンな方法を提供します。Javascriptオブジェクトの自己更新UIを作成できます。

  • これは純粋なJavaScriptライブラリであり、任意のWebフレームワークで動作します。これはJQueryに代わるものではありませんが、スマートな機能を提供する補足として機能します。

  • KnockoutJSライブラリファイルは非常に小さく軽量です。

  • KnockoutJSは、他のフレームワークから独立しています。他のクライアントまたはサーバー側のテクノロジーと互換性があります。

  • すべてのKnockoutJSの中で最も重要なのはオープンソースであるため、無料で使用できます。

  • KnockoutJSは完全に文書化されています。公式サイトには、APIドキュメント、ライブサンプル、インタラクティブチュートリアルを含む完全なドキュメントがあります。

KnockoutJSの使い方はとても簡単です。HTMLページで<script>タグを使用してJavaScriptファイルを参照するだけです。

Knockout.jsには、次の方法でアクセスできます-

  • Knockout.jsのプロダクションビルドは、公式Webサイトからダウンロードできます。

    次の画像のようなページが表示されます。ダウンロードリンクをクリックすると、最新のknockout.jsファイルが表示されます。

次のコードに示すように、ファイルを参照します。

<script type = 'text/javascript' src = 'knockout-3.3.0.js'></script>

ダウンロードしたファイルが保存されている場所と一致するようにsrc属性を更新します。

  • CDNからKnockoutJSライブラリを参照できます-

    • 次のように、コードでMicrosoft AjaxCDNのKnockoutJSライブラリを参照できます。

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"></script>
  • または、次のようにCDNJSからKnockoutJSライブラリの縮小バージョンを参照することもできます。

<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js" 
   type = "text/javascript"></script>

Note −このチュートリアルのすべての章で、KnockoutJSライブラリのCDNバージョンを参照しました。

KnockoutJSは、Model-View-ViewModel(MVVM)パターンに基づいています。このパターンについては、KnockoutJS-MVVMFrameworkの章で詳しく説明します。まず、KnockoutJSの簡単な例を見てみましょう。

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Simple Example</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
         type = "text/javascript"></script>
   </head>

   <body>
      <!-- This is called "view" of HTML markup that defines the appearance of UI -->

      <p>First String: <input data-bind = "value: firstString" /></p>
      <p>Second String: <input data-bind = "value: secondString" /></p>

      <p>First String: <strong data-bind = "text: firstString">Hi</strong></p>
      <p>Second String: <strong data-bind = "text: secondString">There</strong></p>

      <p>Derived String: <strong data-bind = "text: thirdString"></strong></p>

      <script>
         <!-- This is called "viewmodel". This javascript section defines the data and 
            behavior of UI -->

         function AppViewModel() {
            this.firstString = ko.observable("Enter First String");
            this.secondString = ko.observable("Enter Second String");

            this.thirdString = ko.computed(function() {
               return this.firstString() + " " + this.secondString();
            }, this);
         }

         // Activates knockout.js
         ko.applyBindings(new AppViewModel());
      </script>

   </body>
</html>

次の行は、KnockoutJSライブラリを参照しています。

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"> </script>

この行はKnockoutJSライブラリを参照しています。

2つの入力ボックスがあります。 First String そして Second String。これらの2つの変数は、ViewModelでそれぞれEnter FirstStringとEnterSecondStringの値で初期化されます。

<p>First String: < input data-bind = "value: firstString" /> </p>

これは、ViewModelからHTML要素に値をバインドする方法です。 'data-bind' 本文セクションの属性。

ここで、「firstString」はViewModel変数を参照します。

this.firstString = ko.observable("Enter First String");

ko.observable は、基になるViewModelデータを更新できるように、値の変更を監視する概念です。

これをよりよく理解するために、最初の入力ボックスを「Hello」に更新し、2番目の入力ボックスを「TutorialsPoint」に更新しましょう。値が同時に更新されるのがわかります。この概念については、KnockoutJS-Observablesの章で詳しく説明します。

this.thirdString = ko.computed(function() {
   return this.firstString() + " " + this.secondString();
}, this);

次に、viewmodelで関数を計算しました。この関数は、前述の2つの文字列に基づいて3番目の文字列を導出します。したがって、これらの文字列に加えられた更新は、この派生文字列に自動的に反映されます。これを実現するために追加のコードを記述する必要はありません。これは単純な例です。この概念については、KnockoutJS-ComputedObservablesの章で学習します。

出力

上記のコードを次のように保存します my_first_knockoutjs_program.html。このファイルをブラウザで開くと、次のような出力が表示されます。

文字列を「Hello」と「TutorialsPoint」に変更すると、出力が次のように変わります。

KnockoutJSは、シングルページアプリケーションに広く使用されています-サーバーのラウンドトリップを削減するシングルページの負荷で必要なすべてのデータを動的に取得する機能を備えて作成されたWebサイト。

KnockoutJSはクライアント側のフレームワークです。これは、HTMLをドメインデータに非常に簡単にバインドできるJavaScriptライブラリです。Model-View-ViewModel(MVVM)と呼ばれるパターンを実装します。ObservablesはKnockoutJSの魔法の要素です。Observable属性のため、すべてのデータは同期されたままです。

建築

見る

ビューは、HTML要素とCSSスタイルを使用して作成されたユーザーインターフェイスに他なりません。

KnockoutJSを使用して、HTMLDOM要素をデータモデルにバインドできます。これは、「データバインド」の概念を使用して、ViewとViewModel間の双方向のデータバインディングを提供します。つまり、UIで行われた更新はデータモデルに反映され、データモデルで行われた変更はUIに反映されます。knockoutJSを使用して自己更新UIを作成できます。

ViewModel

ViewModelはJavaScriptオブジェクトであり、データを表すために必要なプロパティと関数が含まれています。ViewとViewModelは、HTMLで使用される宣言型のデータバインドの概念で接続されています。これにより、ViewModelを変更せずにHTMLを簡単に変更できます。KnockoutJSは、Observablesを使用して、それらの間の自動データ更新を処理します。

データの同期は、DOM要素をデータモデルにバインドすることで実現されます。最初にデータバインドを使用し、次にObservablesを使用してこれら2つのコンポーネントを更新します。このデータの同期により、依存関係の追跡は自動的に行われます。それを達成するために追加のコーディングは必要ありません。KnockoutJSを使用すると、ディスプレイと基になるデータの間に直接接続を作成できます。

アプリケーション固有の動作用のカスタムバインディングと呼ばれる独自のバインディングを作成できます。このようにして、Knockoutは、データをHTMLに変換する方法を直接制御します。

モデル

モデルはサーバー上のドメインデータであり、ViewModelからリクエストが送受信されるときに操作されます。

データは、データベース、Cookie、またはその他の形式の永続ストレージに保存できます。KnockoutJSは、それがどのように保存されるかについて心配しません。保存されたデータとKnockoutJSの間で通信するのは、プログラマーの責任です。

ほとんどの場合、データはAjax呼び出しを介して保存およびロードされます。

Model-View-ViewModel (MVVM)ソフトウェアアプリケーションを開発するためのアーキテクチャデザインパターンです。MVVMは、2005年にMicrosoftアーキテクトのJohn Gossmanによって開発されました。このパターンは、Model-View-Controller(MVC)パターンから派生しています。MVVMの利点は、アプリケーション層のグラフィカルユーザーインターフェイスをビジネスロジックから分離することです。MVVMは、基になるモデルからのデータを非常に簡単に表現および管理できるように処理する責任があります。MVVMのViewModelは、Viewの状態とアクションの抽象バージョンを表します。

ビュークラスは、ModelクラスとViewModelクラスが存在することを認識していません。また、ModelクラスとViewModelは、Viewが存在することを認識していません。モデルは、ViewModelとViewが存在することも認識していません。

建築

見る

ビューは、データを表すためにマークアップ言語を使用して作成されたグラフィカルユーザーインターフェイスです。ビューは、モデルデータに間接的に接続するデータバインドの概念を介してViewModelのプロパティにバインドします。ViewModelで変更を行う場合は、ビューを変更する必要はありません。ViewModelでデータに加えられた変更は、バインドによりViewに自動的に伝播されます。

モデル

モデルは、リアルタイムデータを保持するドメインデータまたはビジネスオブジェクトです。モデルには動作がありません。動作は主にビジネスロジックで実装されます。

ViewModel

ViewModelは、ModelとViewの表示ロジックからのデータが一緒にバンドルされる中心的な場所です。ViewModelは、データの動的な状態を保持します。ViewとViewModelの間には、相互に通信するための暗黙的なバインダーがあります。このバインディングには、宣言型データとコマンドバインディングが含まれます。ViewとViewModelの同期は、このバインディングによって実現されます。Viewで行われた変更はすべてViewModelに反映され、同様にViewModelでの変更は自動的にViewに反映されます。この双方向バインディングメカニズムの存在は、このMVVMパターンの重要な側面です。

KnockoutJSは、次の3つの重要な概念に基づいて構築されています。

  • オブザーバブルとそれらの間の依存関係の追跡-DOM要素は「data-bind」を介してViewModelに接続されます。彼らはObservablesを通じて情報を交換します。これにより、依存関係の追跡が自動的に処理されます。

  • UIとViewModel間の宣言型バインディング-DOM要素は「data-bind」の概念を介してViewModelに接続されます。

  • 再利用可能なコンポーネントを作成するためのテンプレート作成-テンプレート作成は、複雑なWebアプリケーションを作成するための堅牢な方法を提供します。

この章では、オブザーバブルについて学習します。

名前が示すように、ViewModelデータ/プロパティをObservableとして宣言すると、毎回のデータ変更は、データが使用されるすべての場所に自動的に反映されます。これには、関連する依存関係の更新も含まれます。KOがこれらの処理を行い、これを実現するために追加のコードを記述する必要はありません。

Observableを使用すると、UIとViewModelを動的に通信させることが非常に簡単になります。

構文

関数でViewModelプロパティを宣言する必要があります ko.observable() それを観察可能にするために。

this.property = ko.observable('value');

Observableの使用法を示す次の例を見てみましょう。

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Observable Example</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
         type = "text/javascript"></script>
   </head>
   
   <body>
      <!-- This is called "view" of HTML markup that defines the appearance of UI -->

      <p>Enter your name: <input data-bind = "value: yourName" /></p>
      <p>Hi <strong data-bind = "text: yourName"></strong> Good Morning!!!</p>

      <script>
         <!-- This is called "viewmodel". This javascript section defines the data and behavior of UI -->

         function AppViewModel() {
            this.yourName = ko.observable("");
         }

         // Activates knockout.js
         ko.applyBindings(new AppViewModel());
      </script>
   </body>
</html>

次の行は入力ボックス用です。ご覧のとおり、data-bind属性を使用してyourName値をViewModelにバインドしました。

<p>Enter your name: <input data-bind = "value: yourName" /> <p>

次の行は、yourNameの値を出力するだけです。ここでは、値を読み取るだけなので、データバインドタイプがテキストであることに注意してください。

<p>Hi <strong data-bind = "text: yourName"></strong> Good Morning!!!</p>

次の行で、ko.observableは、データの変更についてyourName変数を監視します。変更があると、対応する場所も変更された値で更新されます。次のコードを実行すると、入力ボックスが表示されます。その入力ボックスを更新すると、新しい値は、使用されている場所に反映または更新されます。

this.yourName = ko.observable("");

出力

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します first_observable_pgm.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • 名前をScottとして入力し、名前が出力に反映されていることを確認します。

データの変更は、UIまたはViewModelのいずれかから行うことができます。データがどこから変更されたかに関係なく、UIとViewModelはそれらの間で同期を維持します。これにより、双方向のバインディングメカニズムになります。上記の例では、入力ボックスで名前を変更すると、ViewModelは新しい値を取得します。ViewModel内からyourNameプロパティを変更すると、UIは新しい値を受け取ります。

オブザーバブルの読み取りと書き込み

次の表に、Observablesで実行できる読み取りおよび書き込み操作を示します。

シニア番号 読み取り/書き込み操作と構文
1

Read

値を読み取るには、次のようなパラメーターを指定せずにObservableプロパティを呼び出すだけです。AppViewModel.yourName();

2

Write

Observableプロパティに値を書き込んだり更新したりするには、次のようなパラメーターで目的の値を渡すだけです。AppViewModel.yourName( 'Bob');

3

Write multiple

複数のViewModelプロパティは、次のようなチェーン構文を使用して1行で更新できます。AppViewModel.yourName( 'Bob')。yourAge(45);

観測可能な配列

Observable宣言は、単一のオブジェクトのデータ変更を処理します。ObservableArrayは、オブジェクトのコレクションで機能します。これは、複数のタイプの値を含む複雑なアプリケーションを処理し、ユーザーの操作に基づいてそれらのステータスを頻繁に変更する場合に非常に便利な機能です。

構文

this.arrayName = ko.observableArray();    // It's an empty array

監視可能な配列は、その中のどのオブジェクトが追加または削除されたかのみを追跡します。個々のオブジェクトのプロパティが変更されたかどうかは通知されません。

初めて初期化する

配列を初期化すると同時に、次のように初期値をコンストラクターに渡すことで、配列をObservableとして宣言できます。

this.arrayName = ko.observableArray(['scott','jack']);

ObservableArrayからの読み取り

Observable配列要素には次のようにアクセスできます。

alert('The second element is ' + arrayName()[1]);

ObservableArray関数

KnockoutJSには、独自のObservable配列関数のセットがあります。−

  • これらの機能はすべてのブラウザで機能します。

  • これらの関数は、依存関係の追跡を自動的に処理します。

  • 構文は使いやすいです。たとえば、要素を配列に挿入するには、arrayName()。push( 'value')の代わりにarrayName.push( 'value')を使用する必要があります。

以下は、さまざまなObservableArrayメソッドのリストです。

シニア番号 方法と説明
1 push( 'value')

配列の最後に新しいアイテムを挿入します。

2 ポップ()

配列から最後の項目を削除して返します。

3 unshift( 'value')

配列の先頭に新しい値を挿入します。

4 シフト()

配列から最初の項目を削除して返します。

5 逆行する()

配列の順序を逆にします。

6 ソート()

配列アイテムを昇順で並べ替えます。

7 splice(start-index、end-index)

start-indexとend-indexの2つのパラメーターを受け入れ、最初から最後のインデックスから始まる項目を削除して、配列として返します。

8 indexOf( 'value')

この関数は、指定されたパラメーターの最初の出現のインデックスを返します。

9 スライス(開始インデックス、終了インデックス)

このメソッドは、配列の一部をスライスします。start-indexからend-indexまでのアイテムを返します。

10 すべて削除する()

すべてのアイテムを削除し、それらを配列として返します。

11 remove( 'value')

パラメータに一致するアイテムを削除し、配列として返します。

12 remove(function(item){condition})

条件を満たすアイテムを削除し、配列として返します。

13 remove([値のセット])

指定された値のセットに一致するアイテムを削除します。

14

destroyAll()

プロパティ_destroyを使用して、配列内のすべてのアイテムを値trueでマークします。

15

destroy('value')

パラメータに等しいアイテムを検索し、値がtrueの特別なプロパティ_destroyでマークします。

16

destroy(function(item) { condition})

条件を満たすすべてのアイテムを検索し、真の値を持つプロパティ_destroyでマークします。

17

destroy([set of values])

指定された値のセットに一致するアイテムを検索し、それらを真の値を持つ_destroyとしてマークします。

Note − ObservableArraysのDestroyおよびDestroyAll関数は、ほとんどが「RubyonRails」開発者専用です。

destroyメソッドを使用すると、対応するアイテムはその時点では実際には配列から削除されませんが、UIで読み取れないように、プロパティ_destroytrue値でマークすることで非表示になります。trueに等しい_destroyとしてマークされたアイテムは、JSONオブジェクトグラフの処理中に後で削除されます。

Computed Observableは、1つ以上のObservableに依存し、基礎となるObservable(依存関係)が変更されるたびに自動的に更新される関数です。

計算されたオブザーバブルは連鎖させることができます。

構文

this.varName = ko.computed(function(){
   ...
   ... //  function code
   ...
},this);

ComputedObservablesの使用法を示す次の例を見てみましょう。

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Computed Observables</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"></script>
   </head>

   <body>
      <p>Enter first number: <input data-bind = "value: a" /></p>
      <p>Enter second number: <input data-bind = "value: b"/></p>
      <p>Average := <span data-bind="text: totalAvg"></span></p>

      <script>
         function MyViewModel() {
            this.a = ko.observable(10);
            this.b = ko.observable(40);

            this.totalAvg = ko.computed(function() {

               if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
                  this.a(Number(this.a()));   //convert string to Number
                  this.b(Number(this.b()));   //convert string to Number
               }

               total = (this.a() + this.b())/2 ;
               return total;
            },this);
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

次の行で、最初の2つは入力値を受け入れるためのものです。3行目は、これら2つの数値の平均を出力します。

<p>Enter first number: <input data-bind = "value: a" /></p>
<p>Enter second number: <input data-bind = "value: b"/></p>
<p>Average := <span data-bind = "text: totalAvg"></span></p>

次の行では、オブザーバブルのタイプ a そして bViewModel内で初めて初期化されたときの数値です。ただし、KOでは、UIから受け入れられるすべての入力は、デフォルトで文字列形式です。したがって、算術演算を実行するには、数値に変換する必要があります。

this.totalAvg = ko.computed(function() {
   
   if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
      this.a(Number(this.a()));   //convert string to Number
      this.b(Number(this.b()));   //convert string to Number
   }
   
   total = (this.a() + this.b())/2 ;
   return total;
},this);

次の行では、計算された平均がUIに表示されます。totalAvgのデータバインドタイプは単なるテキストであることに注意してください。

<p>Average := <span data-bind = "text: totalAvg"></span></p>

出力

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します computed-observable.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • テキストボックスに任意の2つの数値を入力し、平均が計算されることを確認します。

「これ」の管理

上記の例では、2番目のパラメーターは次のように提供されていることに注意してください。 this計算関数へ。Observablesを参照することはできませんa() そして b() 提供せずに this

これを克服するために、 self の参照を保持する変数が使用されます this。そうすることで、追跡する必要はありませんthisコード全体。代わりに、self に使える。

次のViewModelコードは、selfを使用して上記の例用に書き直されています。

function MyViewModel(){
   self = this;
   self.a = ko.observable(10);
   self.b = ko.observable(40);

   this.totalAvg = ko.computed(function() {
      
      if(typeof(self.a()) !== "number" || typeof(self.b()) !== "number") {
         self.a(Number(self.a()));   //convert string to Number
         self.b(Number(self.b()));   //convert string to Number
      }
      
      total = (self.a() + self.b())/2 ;
      return total;
   });
}

純粋な計算されたオブザーバブル

ComputedObservableは次のように宣言する必要があります PureObservableが単に値を計算して返すだけで、他のオブジェクトや状態を直接変更していない場合は、ComputedObservable。Pure Computed Observablesは、Knockoutが再評価とメモリ使用量を効率的に管理するのに役立ちます。

サブスクライバーに明示的に通知する

Computed Observableがプリミティブデータ型の値(String、Boolean、Null、およびNumber)を返す場合、実際の値の変更が行われた場合にのみ、そのサブスクライバーに通知されます。これは、Observableが前の値と同じ値を受け取った場合、そのサブスクライバーには通知されないことを意味します。

新しい値が古い値と同じであっても、Computed Observablesを常に明示的にオブザーバーに通知するようにするには、 notify 構文は次のとおりです。

myViewModel.property = ko.pureComputed(function() {
   return ...;    // code logic goes here
}).extend({ notify: 'always' });

変更通知の制限

高価な更新が多すぎると、パフォーマンスの問題が発生する可能性があります。を使用して、Observableから受信する通知の数を制限できます。rateLimit 次のように属性。

// make sure there are updates no more than once per 100-millisecond period
myViewModel.property.extend({ rateLimit: 100 });

プロパティが観察可能であるかどうかを調べる

特定の状況では、プロパティがComputedObservableであるかどうかを確認する必要がある場合があります。以下の関数を使用して、Observableのタイプを識別できます。

シニア番号 関数
1

ko.isComputed

戻り値 true プロパティがComputedObservableの場合。

2

ko.isObservable

戻り値 true プロパティがObservable、Observable array、またはComputedObservableの場合。

3

ko.isWritableObservable

戻り値 trueObservable、Observable array、またはWritable ComputedObservableの場合。(これはko.isWriteableObservableとも呼ばれます)

書き込み可能な計算されたオブザーバブル

Computed Observableは、1つまたは複数の他のObservableから派生しているため、読み取り専用です。ただし、ComputedObservableを書き込み可能にすることは可能です。このためには、書き込まれた値で機能するコールバック関数を提供する必要があります。

これらの書き込み可能なComputedObservableは、通常のObservableと同じように機能します。さらに、読み取りおよび書き込みアクションを妨害するためのカスタムロジックを構築する必要があります。

次のように連鎖構文を使用して、多くのObservablesまたはComputedObservableプロパティに値を割り当てることができます。

myViewModel.fullName('Tom Smith').age(45)

次の例は、Writable ComputableObservableの使用法を示しています。

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Writable Computed Observable</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
   </head>

   <body>
      <p>Enter your birth Date: <input type = "date" data-bind = "value: rawDate" ></p>
      <p><span data-bind = "text: yourAge"></span></p>

      <script>
         function MyViewModel() {
            this.yourAge = ko.observable();
            today = new Date();
            rawDate = ko.observable();

            this.rawDate = ko.pureComputed ({

               read: function() {
                  return this.yourAge;
               },

               write: function(value) {
                  var b = Date.parse(value);    // convert birth date into milliseconds
                  var t = Date.parse(today);    // convert todays date into milliseconds
                  diff = t - b;                 // take difference
                  var y = Math.floor(diff/31449600000);     // difference is converted
                                                            // into years. 31449600000
                                                            //milliseconds form a year.

                  var m = Math.floor((diff % 31449600000)/604800000/4.3);  // calculating
                                                                           // months.
                                                                           // 604800000
                                                                           // milliseconds
                                                                           // form a week.

                  this.yourAge("You are " + y + " year(s) " + m +" months old.");
               },
               owner: this
            });
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

上記のコードでは、 rawDate UIから受け入れられるpureComputedプロパティです。 yourAge Observableはから派生しています rawDate

JavaScriptの日付は、ミリ秒単位で操作されます。したがって、両方の日付(今日の日付と生年月日)がミリ秒に変換されてから、それらの差が年と月に変換されます。

出力

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します writable_computed_observable.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • 生年月日を入力し、年齢が計算されることを確認します。

KnockoutJSの宣言型バインディングは、データをUIに接続するための強力な方法を提供します。

バインディングとObservablesの関係を理解することが重要です。技術的には、これら2つは異なります。通常のJavaScriptオブジェクトをViewModelとして使用でき、KnockoutJSはViewのバインディングを正しく処理できます。

Observableがないと、UIのプロパティは初めて処理されます。この場合、基になるデータの更新に基づいて自動的に更新することはできません。これを実現するには、バインディングをObservableプロパティを参照する必要があります。

バインディング構文

バインディングは2つのアイテムで構成されています。 name そして value。以下は簡単な例です-

Today is : <span data-bind = "text: whatDay"></span>

ここで、textはバインディング名であり、whatDayはバインディング値です。次の構文に示すように、複数のバインディングをコンマで区切ることができます。

Your name: <input data-bind = "value: yourName, valueUpdate: 'afterkeydown'" />

ここでは、各キーが押されると値が更新されます。

バインディング値

バインディング値は single valueliteralvariable またはすることができます JavaScript式。バインディングが無効な式または参照を参照している場合、KOはエラーを生成し、バインディングの処理を停止します。

以下は、バインディングのいくつかの例です。

<!-- simple text binding -->
<p>Enter employee name: <input   -bind = 'value: empName' /></p>

<!-- click binding, call a specific function -->
<button data-bind="click: sortEmpArray">Sort Array</button>

<!-- options binding -->
<select multiple = "true" size = "8" data-bind = "options: empArray , 
   selectedOptions: chosenItem"> </select>

次の点に注意してください-

  • 空白は何の違いもありません。

  • KO 3.0以降では、バインディングに未定義の値を与えるバインディング値をスキップできます。

バインディングコンテキスト

現在のバインディングで使用されているデータは、オブジェクトから参照できます。このオブジェクトは呼ばれますbinding context

コンテキスト階層は、KnockoutJSによって自動的に作成および管理されます。次の表に、KOが提供するさまざまなタイプのバインディングコンテキストを示します。

シニア番号 コンテキストタイプと説明のバインド
1

$root

これは常にトップレベルのViewModelを参照します。これにより、ViewModelを操作するためのトップレベルのメソッドにアクセスできるようになります。これは通常、ko.applyBindingsに渡されるオブジェクトです。

2

$data

このプロパティは非常に似ています thisJavascriptオブジェクトのキーワード。バインディングコンテキストの$ dataプロパティは、現在のコンテキストのViewModelオブジェクトを参照します。

3

$index

このプロパティには、foreachループ内の配列の現在のアイテムのインデックスが含まれています。$ indexの値は、基になるObservable配列が更新されると、自動的に変更されます。明らかに、このコンテキストは次の場合にのみ使用できます。foreach バインディング。

4

$parent

このプロパティは、親のViewModelオブジェクトを参照します。これは、ネストされたループの内側から外部のViewModelプロパティにアクセスする場合に役立ちます。

5

$parentContext

親レベルでバインドされているコンテキストオブジェクトが呼び出されます $parentContext。これはとは異なります$parent。$ parentはデータを参照します。一方、$ parentContextはバインディングコンテキストを指します。たとえば、内部コンテキストから外部foreachアイテムのインデックスにアクセスする必要がある場合があります。

6

$rawdata

このコンテキストは、現在の状況で生のViewModel値を保持します。これは似ています$data but the difference is, if ViewModel is wrapped in Observable, then $データはラップ解除されるだけです。ViewModelと$ rawdataは、実際のObservableデータになります。

7

$component

このコンテキストは、特定のコンポーネント内にいるときに、そのコンポーネントのViewModelを参照するために使用されます。たとえば、コンポーネントのテンプレートセクションにある現在のデータではなく、ViewModelからいくつかのプロパティにアクセスしたい場合があります。

8

$componentTemplateNodes

これは、特定のコンポーネントテンプレート内にいるときに、その特定のコンポーネントに渡されるDOMノードの配列を表します。

以下の用語もバインディングで使用できますが、実際にはバインディングのコンテキストではありません。

  • $context −これは既存のバインディングコンテキストオブジェクトに他なりません。

  • $element −このオブジェクトは、現在のバインディングのDOM内の要素を参照します。

テキストと外観の操作

以下は、テキストと視覚的な外観を処理するためにKOが提供するバインディングタイプのリストです。

シニア番号 製本の種類と使用法
1 表示:<バインディング条件>

特定の条件に応じてHTMLDOM要素を表示または非表示にします。

2 テキスト:<バインディング値>

HTMLDOM要素のコンテンツを設定します。

3 html:

DOM要素のHTMLマークアップコンテンツを設定します。

4 css:<バインディングオブジェクト>

CSSクラスを要素に適用します。

5 スタイル:<バインディングオブジェクト>

要素のインラインスタイル属性を定義します。

6 attr:<バインディングオブジェクト>

要素に属性を動的に追加します。

制御フローバインディングの操作

以下は、KOが提供する制御フローバインディングタイプのリストです。

シニア番号 製本の種類と使用法
1 foreach:

このバインディングでは、各配列項目はループ内のHTMLマークアップで参照されます。

2 if:<バインディング条件>

条件がtrueの場合、指定されたHTMLマークアップが処理されます。それ以外の場合は、DOMから削除されます。

3 ifnot:<バインディング条件>

Ifの否定。条件がtrueの場合、指定されたHTMLマークアップが処理されます。それ以外の場合は、DOMから削除されます。

4 と:

このバインディングは、指定されたオブジェクトのコンテキストでオブジェクトの子要素をバインドするために使用されます。

5 コンポーネント:<コンポーネント名>またはコンポーネント:<コンポーネントオブジェクト>

このバインディングは、コンポーネントをDOM要素に挿入し、オプションでパラメーターを渡すために使用されます。

フォームフィールドバインディングの操作

以下は、KOが提供するフォームフィールドバインディングタイプのリストです。

シニア番号 製本の種類と使用法
1 クリック:<バインディング関数>

このバインディングは、クリックに基づいてDOM要素に関連付けられたJavaScript関数を呼び出すために使用されます。

2 イベント:

このバインディングは、指定されたDOMイベントをリッスンし、それらに基づいて関連するハンドラー関数を呼び出すために使用されます。

3 送信:<バインディング関数>

このバインディングは、関連付けられたDOM要素が送信されたときにJavaScript関数を呼び出すために使用されます。

4 enable:

このバインディングは、指定された条件に基づいて特定のDOM要素を有効にするために使用されます。

5 無効化:<バインディング値>

このバインディングは、パラメーターがtrueと評価されたときに、関連付けられたDOM要素を無効にします。

6 値:<バインディング値>

このバインディングは、それぞれのDOM要素の値をViewModelプロパティにリンクするために使用されます。

7 textInput:<バインディング値>

このバインディングは、テキストボックスまたはtextareaとViewModelプロパティの間に双方向バインディングを作成するために使用されます。

8 hasFocus:<バインディング値>

このバインディングは、ViewModelプロパティを介してHTMLDOM要素のフォーカスを手動で設定するために使用されます。

9 チェック済み:

このバインディングは、チェック可能なフォーム要素とViewModelプロパティの間にリンクを作成するために使用されます。

10 オプション:

このバインディングは、select要素のオプションを定義するために使用されます。

11 selectedOptions:

このバインディングは、マルチリスト選択フォームコントロールで現在選択されている要素を操作するために使用されます。

12 uniqueName:

このバインディングは、DOM要素の一意の名前を生成するために使用されます。

KnockoutJsは、値が更新されると、依存関係を自動的に追跡します。と呼ばれる単一のオブジェクトがありますdependency tracker (ko.dependencyDetection)は、依存関係をサブスクライブするための2つのパーティ間の中間として機能します。

以下は、依存関係追跡のアルゴリズムです。

Step 1 −計算されたオブザーバブルを宣言すると、KOはすぐにその評価関数を呼び出して初期値を取得します。

Step 2−サブスクリプションは、評価者が読み取るオブザーバブルに設定されます。アプリケーションでは、使用されなくなった古いサブスクリプションが破棄されます。

Step 3 − KOは最終的に、更新された計算済みオブザーバブルを通知します。

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJS How Dependency Tracking Works</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div>
         <form data-bind = "submit: addFruits">
            <b>Add Fruits:</b>
            <input data-bind = 'value: fruitToAdd, valueUpdate: "afterkeydown"'/>
            <button type = "submit" data-bind = "enable: fruitToAdd().length > 0">Add</button>
            <p><b>Your fruits list:</b></p>
            <select multiple = "multiple" width = "50" data-bind = "options: fruits"> </select>
         </form>
      </div>
      
      <script>
         var Addfruit = function(fruits) {
            this.fruits = ko.observableArray(fruits);
            this.fruitToAdd = ko.observable("");
            
            this.addFruits = function() {
               
               if (this.fruitToAdd() != "") {
                  this.fruits.push(this.fruitToAdd());   // Adds a fruit
                  this.fruitToAdd("");                   // Clears the text box
               }
                
            }.bind(this);                                // "this" is the view model
         };

         ko.applyBindings(new Addfruit(["Apple", "Orange", "Banana"]));
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します dependency_tracking.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • 果物の名前を入力して、[追加]ボタンをクリックします。

ピークを使用した依存関係の制御

Computed Observableは、依存関係を作成せずに、を使用してアクセスできます。 peek関数。計算されたプロパティを更新することにより、Observableを制御します。

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJs Controlling Dependencies Using Peek</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div class = "logblock">
         <h3>Computed Log</h3>
         <pre class = "log" data-bind = "html: computedLog"></pre>
      </div>

      <script>
         function AppData() {
            this.firstName = ko.observable('John');
            this.lastName = ko.observable('Burns');
            this.computedLog = ko.observable('Log: ');
            
            this.fullName = ko.computed(function () {
               var value = this.firstName() + " " + this.lastName();
               this.computedLog(this.computedLog.peek() + value + '; <br/>');
               return value;
            }, this);

            this.step = ko.observable(0);
            this.next = function () {
               this.step(this.step() === 2 ? 0 : this.step()+1);
            };
         };
         
         ko.applyBindings(new AppData());
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します dependency_tracking_peek.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

観察

計算された依存関係内の依存関係を無視する

ザ・ ko.ignoreDependencies関数は、計算された依存関係内で追跡したくない依存関係を無視するのに役立ちます。以下はその構文です。

ko.ignoreDependencies( callback, callbackTarget, callbackArgs );

循環依存が意味をなさない理由

KOがComputedObservableを評価している場合、依存するComputedObservableの評価は再開されません。したがって、依存関係チェーンにサイクルを含めることは意味がありません。

Template繰り返し使用できるDOM要素のセットです。テンプレートを使用すると、DOM要素の重複を最小限に抑えることができるため、複雑なアプリケーションを簡単に構築できます。

テンプレートを作成する方法は2つあります。

  • Native templating−このメソッドは、foreach、with、ifなどの制御フローバインディングをサポートします。これらのバインディングは、要素に存在するHTMLマークアップをキャプチャし、ランダムなアイテムのテンプレートとして使用します。このテンプレートには外部ライブラリは必要ありません。

  • String-based templating− KOはサードパーティエンジンに接続してViewModel値を渡し、結果のマークアップをドキュメントに挿入します。たとえば、JQuery.tmplやUnderscoreEngineなどです。

Syntax

template: <parameter-value>

<script type = "text/html" id = "template-name">
   ...
   ...   // DOM elemets to be processed
   ...
</script>

ご了承ください type として提供されます text/html KOに通知するスクリプトブロックでは、実行可能ブロックではなく、レンダリングする必要がある単なるテンプレートブロックです。

Parameters

以下のプロパティの組み合わせをパラメータ値としてテンプレートに送信できます。

  • name −これはテンプレートの名前を表します。

  • nodes−これは、テンプレートとして使用されるDOMノードの配列を表します。nameパラメーターが渡された場合、このパラメーターは無視されます。

  • data −これはテンプレートを介して表示されるデータに他なりません。

  • if −指定された条件がtrueまたはtrueのような値になる場合、テンプレートが提供されます。

  • foreach −foreach形式でテンプレートを提供する。

  • as −これは、foreach要素にエイリアスを作成するためだけのものです。

  • afterAdd, afterRender, beforeRemove −これらはすべて、実行される操作に応じて実行される呼び出し可能な関数を表します。

観察

名前付きテンプレートのレンダリング

テンプレートは、制御フローバインディングとともに使用される場合、DOM内のHTMLマークアップによって暗黙的に定義されます。ただし、必要に応じて、テンプレートを別の要素に分解し、名前で参照することができます。

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Named Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', data: friend1 }"></div>
      <div data-bind = "template: { name: 'friend-template', data: friend2 }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friend1 = { 
               name: 'Smith', 
               contactNumber: 4556750345, 
               email: '[email protected]' 
            };
            
            this.friend2 = { 
               name: 'Jack', 
               contactNumber: 6789358001, 
               email: '[email protected]' 
            };
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します template-named.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • ここでは、friend-templateが2回使用されています。

テンプレートで「foreach」を使用する

以下は使用例です foreach テンプレート名と一緒にパラメータ。

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - foreach used with Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', foreach: friends }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = [
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
               { name: 'Lisa', contactNumber: 4567893131, email: '[email protected]' }
            ]
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します template-foreach.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • ここでは、foreachコントロールがテンプレートバインディングで使用されています。

foreachアイテムのキーワードとして使用するエイリアスの作成

以下は、foreachアイテムのエイリアスを作成する方法です-

<div data-bind = "template: { 
   name: 'friend-template', 
   foreach: friends, 
   as: 'frnz' 
}"></div>

エイリアスを作成することで、foreachループ内から親オブジェクトを簡単に参照できるようになります。この機能は、コードが複雑で複数のレベルにネストされている場合に役立ちます。

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - using alias in Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <ul data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends, 
         as: 'frnz' 
      }"></ul>

      <script type = "text/html" id = "friend-template">
         <li>
            <h3 data-bind = "text: name"></h3>
            <span>Contact Numbers</span>
            <ul data-bind = "template: { 
               name : 'contacts-template', 
               foreach:contactNumber, 
               as: 'cont'
            } "></ul>
            <p>Email-id: <span data-bind = "text: email"></span></p>
         </li>
      </script>

      <script type = "text/html" id = "contacts-template">
         <li>
            <p><span data-bind = "text: cont"></span></p>
         </li>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = ko.observableArray ( [
               { 
                  name: 'Smith', 
                  contactNumber: [ 4556750345, 4356787934 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Jack', 
                  contactNumber: [ 6789358001, 3456895445 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Lisa', 
                  contactNumber: [ 4567893131, 9876456783, 1349873445 ],  
                  email: '[email protected]' 
               }
            ]);
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します template-as-alias.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • アレイのフルネームの代わりにエイリアスが使用されます。

afterAdd、beforeRemove、およびafterRenderの使用

テンプレートによって作成されたDOM要素に対して追加のカスタムロジックを実行する必要がある場合があります。このような場合、以下のコールバックを使用できます。次にforeach要素を使用していると考えてください-

afterAdd −この関数は、foreachに記載されている配列に新しい項目が追加されたときに呼び出されます。

beforeRemove −この関数は、foreachに記載されている配列からアイテムを削除する直前に呼び出されます。

afterRender −ここで説明する関数は、foreachがレンダリングされ、新しいエントリが配列に追加されるたびに呼び出されます。

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Use of afterRender Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
      <script src = "https://code.jquery.com/jquery-2.1.3.min.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends , 
         afterRender: afterProcess
      }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
         <button data-bind = "click: $root.removeContact">remove </button>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            self = this;
            this.friends = ko.observableArray ([
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
            ])

            this.afterProcess = function(elements, data){
               $(elements).css({color: 'magenta' });
            }

            self.removeContact = function() {
               self.friends.remove(this);
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します template-afterrender.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • ここでは、foreachがレンダリングされるたびにafterProcess関数が実行されます。

テンプレートを動的に選択する

使用可能なテンプレートが複数ある場合は、次のように名前を付けることで動的に1つを選択できます。 observableパラメータ。したがって、名前パラメータが変更されるとテンプレート値が再評価され、データが再レンダリングされます。

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Dynamic Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: whichTemplate, 
         foreach: friends 
      }"></div>

      <script type = "text/html" id = "only-phon">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
      </script>

      <script type = "text/html" id = "only-email">
         <h3 data-bind = "text: name"></h3>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
   
            this.friends = ko.observableArray ([
               {
                  name: 'Smith', 
                  contactNumber: 4556750345, 
                  email: '[email protected]', 
                  active: ko.observable(true)
               },
               
               {
                  name: 'Jack', 
                  contactNumber: 6789358001, 
                  email: '[email protected]', 
                  active: ko.observable(false)
               },
            ]);

            this.whichTemplate = function(friends) {
               return friends.active() ? "only-phon" : "only-email";
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します template-dynamic.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • 使用するテンプレートは、アクティブなフラグ値に応じて決定されます。

外部文字列ベースのエンジンの使用

ネイティブテンプレートは、ネストされたコードブロックでも、さまざまな制御フロー要素で完全に機能します。KOは、UnderscoreテンプレートエンジンやJQuery.tmplなどの外部テンプレートライブラリと統合する方法も提供します。

公式サイトで述べたように、JQuery.tmplは2011年12月以降、活発に開発されていません。したがって、KOのネイティブテンプレートは、JQuery.tmplやその他の文字列ベースのテンプレートエンジンの代わりにのみ推奨されます。

詳しくは公式サイトをご覧ください。

コンポーネントは、大規模なアプリケーションを構築し、コードの再利用性を促進するためのUIコードを整理するための巨大な方法です。

他のコンポーネントから継承またはネストされます。ロードと構成については、独自の規則またはロジックを定義します。

アプリケーションまたはプロジェクト全体で再利用できるようにパッケージ化されています。アプリケーションまたは小さなコントロール/ウィジェットの完全なセクションを表します。必要に応じてロードまたはプリロードできます。

コンポーネント登録

コンポーネントは、を使用して登録できます ko.components.register()API。KOでコンポーネントをロードして表すのに役立ちます。登録には、構成を含むコンポーネント名が必要です。構成は、viewModelとテンプレートを決定する方法を指定します。

Syntax

コンポーネントは次のように登録できます-

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • ザ・ component-name 空でない任意の文字列にすることができます。

  • viewModel オプションであり、次のセクションにリストされている任意のviewModel形式を使用できます。

  • template が必要であり、次のセクションにリストされているテンプレート形式のいずれかを取ることができます。

ViewModelの記述

次の表に、コンポーネントの登録に使用できるviewModel形式を示します。

シニア番号 viewModelフォームと説明
1

constructor function

コンポーネントごとに個別のviewModelオブジェクトを作成します。オブジェクトまたは関数は、コンポーネントビューでバインドするために使用されます。

function SomeComponentViewModel(params) {
   this.someProperty = params.something;
}
ko.components.register('component name', {
   viewModel: SomeComponentViewModel,
   template: ...
});
2

shared object instance

viewModelオブジェクトインスタンスは共有されます。インスタンスプロパティは、オブジェクトを直接使用するために渡されます。

var sharedViewModelInstance = { ... };

ko.components.register('component name', {
   viewModel: { instance: sharedViewModelInstance },
   template: ...
});
3

createViewModel

ファクトリとして機能し、オブジェクトを返すことができるビューモデルとして使用できる関数を呼び出します。

ko.components.register('component name', {  
   viewModel: {  
      createViewModel: function (params, componentInfo) {  
         ...       //function code  
         ...
      }  
   },  
   template: ....  
});
4

AMD module

これは、モジュールと依存関係の両方が非同期にロードされるモジュールを定義するためのモジュール形式です。

ko.components.register('component name', {
   viewModel: { require: 'some/module/name' },
   template: ...
});

define(['knockout'], function(ko) {
   function MyViewModel() {
      // ...
   }

   return MyViewModel;
});

テンプレートを述べる

次の表に、コンポーネントの登録に使用できるテンプレート形式を示します。

シニア番号 テンプレートフォーム
1

element ID

ko.components.register('component name', {
   template: { element: 'component-template' },
   viewModel: ...
});
2

element instance

var elemInstance = document.getElementById('component-template');

ko.components.register('component name', {
   template: { element: elemInstance },
   viewModel: ...
});
3

string of markup

ko.components.register('component name', {
   template: '<input data-bind = "value: yourName" />\
      <button data-bind = "click: addEmp">Add Emp </button>',
   viewModel: ...
});
4

DOM nodes

var emp = [
   document.getElementById('node 1'),
   document.getElementById('node 2'),
];

ko.components.register('component name', {
   template: emp,
   viewModel: ...
});
5

document fragement

ko.components.register('component name', {
   template: someDocumentFragmentInstance,
   viewModel: ...
});
6

AMD module

ko.components.register('component name', {
   template: { require: 'some/template' },
   viewModel: ...
});

単一のAMDモジュールとして登録されたコンポーネント

AMDモジュールは、viewModel / templateのペアを使用せずに、コンポーネントを単独で登録できます。

ko.components.register('component name',{ require: 'some/module'});

コンポーネントのバインド

コンポーネントのバインドには2つの方法があります。

  • Full syntax−パラメータとオブジェクトをコンポーネントに渡します。以下のプロパティを使用して合格できます。

    • name −コンポーネント名を追加します。

    • params −コンポーネントのオブジェクトに複数のパラメータを渡すことができます。

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax −文字列をコンポーネント名として渡し、パラメータは含まれません。

<div data-bind = 'component: "component name"'></div>
  • Template-only components −コンポーネントは、viewModelを指定せずにテンプレートを定義することしかできません。

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element−コンポーネントは、追加のコンテナ要素を使用せずに使用できます。これは、containerless flow コメントタグと同様のコントロール。

<!--ko.component: ""-->
<!--/ko-->

カスタム要素

カスタム要素は、コンポーネントをレンダリングする方法です。ここでは、コンポーネントがバインドされるプレースホルダーを定義する代わりに、自己記述的なマークアップ要素名を直接記述することができます。

<products-list params = "name: userName, type: userType"></products-list>

パラメータの受け渡し

params属性は、パラメーターをコンポーネントviewModelに渡すために使用されます。これは、データバインド属性に似ています。params属性の内容は、JavaScriptオブジェクトリテラルのように(データバインド属性のように)解釈されるため、任意のタイプの任意の値を渡すことができます。次の方法でパラメータを渡すことができます-

  • Communication between parent and child components−コンポーネントはそれ自体ではインスタンス化されないため、viewmodelプロパティはコンポーネントの外部から参照され、子コンポーネントのviewmodelによって受信されます。たとえば、次の構文で次のことがわかります。ModelValue 子viewModelコンストラクターによって受信される親viewmodelです ModelProperty

  • Passing observable expressions −paramsパラメーターに3つの値があります。

    • simpleExpression−数値です。オブザーバブルは含まれていません。

    • simpleObservable−親viewModelで定義されているインスタンスです。親viewModelは、子viewModelによって行われたobservableの変更を自動的に取得します。

    • observableExpression−式は、式がそれ自体で評価されるときにオブザーバブルを読み取ります。観測可能な値が変化すると、式の結果も時間とともに変化する可能性があります。

次のようにパラメータを渡すことができます-

<some-component
   params = 'simpleExpression: 1 + 1,
      simpleObservable: myObservable,
      observableExpression: myObservable() + 1'>
</some-component>

次のようにviewModelのパラメーターを渡すことができます-

<some-component
   params = 'objectValue:{a: 3, b: 2},
      dateValue: new date(),
      stringValue: "Hi",
      numericValue:123,
      boolValue: true/false,
      ModelProperty: ModelValue'>
</some-component>

コンポーネントへのマークアップの受け渡し

受信したマークアップはコンポーネントの作成に使用され、出力の一部として選択されます。次のノードは、コンポーネントテンプレートの出力の一部として渡されます。

template: { nodes: $componentTemplateNodes }

カスタム要素タグ名の制御

を使用してコンポーネントに登録する名前 ko.components.register、同じ名前がカスタム要素タグ名に対応します。カスタム要素タグ名をオーバーライドして、を使用して制御することで変更できますgetComponentNameForNode

ko.components.getComponentNameForNode = function(node) {
   ...
   ...   //function code
   ...
}

カスタム要素の登録

デフォルトのコンポーネントローダーが使用されているため、コンポーネントがを使用して登録されている場合、カスタム要素をすぐに使用できるようになります。 ko.components.register。使用していない場合ko.components.registerカスタムコンポーネントローダーを実装すると、任意の要素名を定義してカスタム要素を使用できます。使用時に設定を指定する必要はありませんko.components.register カスタムコンポーネントローダーはそれを使用しなくなったためです。

ko.components.register('custom-element', { ......... });

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Components</title>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
   </head>
   
   <body>
      <!--params attribute is used to pass the parameter to component viewModel.-->
      <click params = "a: a, b: b"></click>

      <!--template is used for a component by specifying its ID -->
      <template id = "click-l">
         <div data-bind = "text: a"></div>

         <!--Use data-bind attribute to bind click:function() to ViewModel. -->
         <button data-bind = "click:function(){callback(1)}">Increase</button>
         <button data-bind = "click:function(){callback(-1)}">Decrease</button>
      </template>

      <script>
         //Here components are registered
         ko.components.register('click', {
            
            viewModel: function(params) {
               self = this;
               this.a = params.a;
               this.b = params.b;

               this.callback = function(num) {
                  self.b(parseInt(num));
                  self.a( self.a() + parseInt(num) );
               };
            },
            template: { element: 'click-l' }
         });

         //keeps an eye on variable for any modification in data
         function viewModel() {
            this.a = ko.observable(2);
            this.b = ko.observable(0);
         }

         ko.applyBindings(new viewModel() );
      </script>
      
   </body>
</html>

Output

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します component_register.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

コンポーネントローダー

コンポーネントローダーは、指定されたコンポーネント名のテンプレート/ viewModelペアを非同期的に渡すために使用されます。

デフォルトのコンポーネントローダー

デフォルトのコンポーネントローダーは、明示的に登録された構成によって異なります。各コンポーネントは、コンポーネントを使用する前に登録されます。

ko.components.defaultLoader

コンポーネントローダーユーティリティの機能

デフォルトのコンポーネントローダーは、次の関数を使用して読み取りと書き込みを行うことができます。

シニア番号 ユーティリティ機能と説明
1

ko.components.register(name, configuration)

コンポーネントが登録されています。

2

ko.components.isRegistered(name)

特定のコンポーネント名がすでに登録されている場合は、trueとして返されます。それ以外の場合はfalseとして返されます。

3

ko.components.unregister(name)

コンポーネント名がレジストリから削除されます。

4

ko.components.get(name, callback)

この関数は、登録されている各ローダーに順番に移動して、コンポーネント名のviewModel / template定義を最初に渡した人を見つけます。次に、を呼び出してviewModel / template宣言を返します。callback。登録されたローダーがコンポーネントについて何も見つけられなかった場合、それは呼び出しますcallback(null)

5

ko.components.clearCachedDefinition(name)

この関数は、指定されたコンポーネントのキャッシュエントリをクリアするときに呼び出すことができます。次回コンポーネントが必要になった場合は、ローダーに再度相談します。

カスタムコンポーネントローダーの実装

カスタムコンポーネントローダーは、次の方法で実装できます。

  • getConfig(name, callback)−名前に応じて、プログラムで構成を渡すことができます。callback(componentConfig)を呼び出して構成を渡すことができます。この場合、オブジェクトcomponentConfigはloadComponentまたはその他のローダーで使用できます。

  • loadComponent(name, componentConfig, callback)−この関数は、構成方法に応じて、構成のviewModelとテンプレート部分を解決します。callback(result)を呼び出して、ビューモデルとテンプレートのペアを渡すことができます。オブジェクトの結果は、次のプロパティによって定義されます。

    • template−必須。DOMノードの配列を返します。

    • createViewModel(params, componentInfo)−オプション。viewModelプロパティの構成方法に応じて、viewModelオブジェクトを返します。

  • loadTemplate(name, templateConfig, callback)− DOMノードは、カスタムロジックを使用してテンプレートで渡されます。オブジェクトtemplateConfigは、オブジェクトcomponentConfigのテンプレートのプロパティです。callback(domNodeArray)は、DOMノードの配列を渡すために呼び出されます。

  • loadViewModel(name, templateConfig, callback) − viewModelファクトリは、カスタムロジックを使用してviewModel構成で渡されます。