この記事は機械翻訳されたものです。

クライアントへの理解

Knockout 入門 (機械翻訳)

John Papa

コード サンプルをダウンロードします。

John Papaデータ バインディング開発は今日、最も人気のある機能の 1 つは、ノックアウト JavaScript ライブラリが HTML と JavaScript の開発にこれらの機能をもたらします。 分離パターン モデル-ビュー-ViewModel (MVVM) などとのシームレスな統合、バインド宣言構文の単純さをプッシュ-プル配管の一般的なタスクはるかコードを簡単に維持し、強化するながらします。 については説明しますこの就任クライアント洞察力列でノックアウトの理想的なシナリオはそれを始めるし、の基本機能を使用する方法を説明する方法について説明します。 ダウンロードすることができますコードの例は、 archive.msdn.microsoft.com/mag201202Client、宣言型の連結を使用して、さまざまな種類のオブジェクトのバインドを作成する方法を示す、MVVM などの分離パターンに従ってデータ中心の JavaScript コードを記述します。

概要

ノックアウト、スティーブ サンダーソンによって開発された、小さな、オープン ソースの JavaScript ライブラリ MIT ライセンスです。 Knockoutjs.com (現在 Internet Explorer 6++、Firefox 2++、クロム、オペラ、サファリを含むすべての主要なブラウザーをサポートします) がノックアウト サポート、ブラウザーの最新リストを維持します。 あなたをノックアウトの開発を開始するのには、いくつかの重要なリソースを必要があります。 開始ノックアウト (現在 2.0.0) の最新バージョンを取得することによって bit.ly/scmtAi とあなたのプロジェクトで参照します。 Visual Studio 2010 を使用している場合は、しかし、私はインストールしてノックアウト (とその他のライブラリを使用して可能性があります) をダウンロードするには、NuGet パッケージ マネージャー Visual Studio 拡張機能を使用して勧めしますので、バージョンを管理し、新しいとき 1 つは警告。 NuGet は、ノックアウトをダウンロードし、2 つの JavaScript ファイルをプロジェクトのスクリプト フォルダーに配置します。 Minified を生産のためお勧めし、名前付け規則ノックアウト - x.y.z のメジャー、マイナーが x.y.z.js とリビジョン番号。 また、人間が判読できる形式でノックアウトのソース コードを含む、ノックアウト-x.y.x-debug.js ファイルです。 私はノックアウトを学習するとき、およびデバッグするときにこのファイルを参照するをお勧めします。

ファイルとは、ASP を使用している場合、HTML ページ (またはかみそりファイル。 を開く純 MVC)、スクリプトを作成して、ノックアウト ライブラリを参照します。

<script src="../scripts/knockout-2.0.0.js" type="text/javascript"></script>

ないバインド

ノックアウト最高最初方法、プッシュ データに HTML 要素をソース オブジェクトからノックアウト (関連するソース コードのサンプル ページ 01 なし knockout.html ダウンロード可能なコード サンプルにあります) を使用せずコードとを調べることによって説明されています。 私は、ノックアウトを使用して、同じ事を達成する方法を紹介します。 私はいくつか HTML の対象要素を開始し、ソース オブジェクトからこれらの HTML 要素にいくつかの値をプッシュ:

<h2>Without Knockout</h2>
<span>Item number:</span><span id="guitarItemNumber"></span>
<br/>
<span>Guitar model:</span><input id="guitarModel"/>
<span>Sales price:</span><input  id="guitarSalesPrice"/>

標準の HTML 要素にデータをプッシュするオブジェクトがある場合は、jQuery を使用できます。

$(document).ready(function () {
  var product = {
    itemNumber: "T314CE",
    model: "Taylor 314ce",
    salePrice: 1199.95
    }; 
    $("#guitarItemNumber").text(product.itemNumber);
    $("#guitarModel").val(product.model);
    $("#guitarSalesPrice").val(product.salePrice);
});

このコード サンプルは、jQuery を使用して、HTML 要素に対応する Id を検索します、それぞれ適切なオブジェクト プロパティの値を設定します。

このコードで 3 つの主なポイントです。 まず、値、ソース オブジェクトから、コードの行を要求する各ソース値からターゲット要素へのマッピングを HTML 要素にプッシュされます。 場合はそこに多くのプロパティが (あったかどうか配列やオブジェクト グラフ)、コードは簡単に扱いになります。 ソース オブジェクトの値を変更すると、値をプッシュするコードが再び呼び出された場合を除き第二に、HTML 要素、変更を反映されません。 第三に、HTML 要素 (ターゲット) の値を変更した場合、変更、基になるソース オブジェクトに反映されません。 もちろん、すべてのコードの多くを解決できませんでしたが、データ バインディングを使用して解決しようとします。

ノックアウトを使用して、同じ HTML を書き換えることができます。

<h2>With Knockout</h2>
<span Item number</span><span data-bind="text: itemNumber"></span>
<br/>
<span>Guitar model:</span><input data-bind="value: model"/>
<span>Sales price:</span><input data-bind="value: salePrice"/>

Id 属性はデータ バインド属性に置き換えられている注意してください。 ApplyBindings 関数を呼び出すと、ノックアウト、特定のオブジェクト (この例では「製品」)、ページをバインドします。 これは、ターゲット要素し、バインド先は、データ コンテキストのプロパティを識別できることを意味製品オブジェクトには、ページのデータ コンテキストを設定します。

ko.applyBindings(product);

ソース オブジェクトの値は、このページ内のターゲット要素にプッシュされます。 (ノックアウトの機能の独自の名前空間内で存在します。コ)対象の要素と、ソース オブジェクトの間のリンクは、データ バインド属性によって定義されています。 最初の span タグを識別するためそのテキスト値を itemNumber プロパティにバインドする必要があります、上記の例では、ノックアウト データ バインド属性表示されます。 ノックアウトし、product.itemNumber プロパティの値を要素にプッシュします。

どのようにノックアウトを使用して簡単にコード減らすことができますを見ることができます。 プロパティおよび要素の増加数としては、必要な唯一の JavaScript コードは、applyBindings 関数です。 ただし、これはまだすべての問題を解決しません。 ソースの変更、また、ソース オブジェクトを更新すると、HTML 変更をターゲットにする場合この例はまだ HTML ターゲットを更新しません。 このため、我々 の偏極量必要があります。

偏極量

ノックアウトが基になる値とリスナーを変更通知オブジェクトは偏極量を通じて追跡の依存関係を追加します (これは、INotifyPropertyChanged インターフェイスの XAML 技術の概念に似ています)。 ノックアウト注目すべきというカスタム関数をオブジェクトのプロパティをラップすることによって観察可能なプロパティを実装します。 オブジェクトのプロパティの設定の代わりに、次のように。

var product = { 
  model: "Taylor 314ce" 
}

ノックアウトを使用して、観測可能なプロパティを指定するプロパティを定義できます。

var product = { 
  model: ko.observable("Taylor 314ce") 
}

偏極量としてプロパティを定義すると、データ バインディングは本当に形をかかります。 示すように、JavaScript コード図 1 ノックアウトを HTML 要素にバインドする 2 つのオブジェクトを示します。 (Data.product1) の最初のオブジェクトでは、2 番目のオブジェクト (data.product2) ノックアウト偏極量としてプロパティを定義しますが、単純なオブジェクト リテラルを使用してそのプロパティを定義します。

図 1 と偏極量なし

$(document).ready(function () {
  var data = {
    product1: {
      id: 1002,
      itemNumber: "T110",
      model: "Taylor 110",
      salePrice: 699.75
    },
    product2: {
      id: ko.observable(1001),
      itemNumber: ko.observable("T314CE"),
      model: ko.observable("Taylor 314ce"),
      salePrice: ko.observable(1199.95)
    }
  };
 
  ko.applyBindings(data);
});

示すようにこのサンプルの HTML 図 2、要素のバインディングの 4 つのセットを示しています。 最初と 2 番目の div タグには、非観測プロパティにバインドされた HTML 要素が含まれています。 最初の div で値が変更されると、何も変更されます。 3 番目と 4 番目の div タグには、観測可能なプロパティにバインドされた HTML 要素が含まれています。 3 番目の div で値が変更されると、4 番目の div 要素が更新されていることに注意してください。 例 02-observable.html を使ってこのデモを試すことができます。

図 2 観測と非偏極量にバインド

<div>
  <h2>Object Literal</h2>
  <span>Item number</span><span data-bind="text: product1.itemNumber"></span>
  <br/>
  <span>Guitar model:</span><input data-bind="value: product1.model"/>
  <span>Sales price:</span><input data-bind="value: product1.salePrice"/>
</div>
<div>
  <h2>Underlying Source Object for Object Literal</h2>
  <span>Item number</span><span data-bind="text: product1.itemNumber"></span>
  <br/>
  <span>Guitar model:</span><span data-bind="text: product1.model"></span>
  <span>Sales price:</span><span data-bind="text: product1.salePrice"></span>
</div>
<div>
  <h2>Observables</h2>
    <span>Item number</span><span data-bind="text: product2.itemNumber"></span>
  <br/>
    <span>Guitar model:</span><input data-bind="value: product2.model"/>
    <span>Sales price:</span><input data-bind="value: product2.salePrice"/>
</div>
<div>
  <h2>Underlying Source Object for Observable Object</h2>
  <span>Item number</span><span data-bind="text: product2.itemNumber"></span>
  <br/>
    <span>Guitar model:</span><span data-bind="text: product2.model"></span>
    <span>Sales price:</span><span data-bind="text: product2.salePrice"></span>
</div>

(注: ノックアウトでは、観測可能なプロパティを使用する必要がありません。 値を 1 回受信しますが、ソース オブジェクトの値を変更する場合は、更新されないことに DOM 要素をする場合は、単純なオブジェクトで十分です。 ただし、ソース オブジェクトし、の同期が維持するには、DOM 要素をターゲットかどうか — 双方向バインディング — 観測可能なプロパティの使用を検討する必要があり、)。

組み込みのバインド

例はこれまで、ノックアウトのテキストと値のバインドにバインドする方法を示しています。 ノックアウト ターゲット DOM 要素にオブジェクトのプロパティをバインドしやすく多くの組み込みバインドがあります。 テキスト バインド ノックアウトをみると、たとえば、それ (Internet Explorer を使用して)、innerText プロパティまたは同等のプロパティ他のブラウザーで設定されます。 テキスト バインドの使用時は、前のテキストが上書きされます。 中にある多くの組み込みのバインドでは、いくつかの最も一般的な表示で見つけることができますの図 3。 ノックアウトのマニュアルにはオンライン左側のナビゲーション ウィンドウでの完全なリストが含まれます (bit.ly/ajRyPj)。

図 3 一般的なノックアウト バインド

サンプル 状況
本文:モデル プロパティ (モデル) は、ターゲット要素のテキスト値をバインドします。 しばしばスパンなどの読み取り専用の要素を使用します。
表示。 isInStock Value プロパティ (isInStock) は、ターゲット要素の可視性にバインドします。 プロパティの値は、true または false に評価されます。
値:価格 (価格) のプロパティの値は、ターゲット要素にバインドします。 多くの場合入力、選択、textarea 要素の使用。
css:クラス名 (クラス名) のプロパティの値は、ターゲット要素にバインドします。 多くの場合設定または DOM 要素の css クラス名を切り替えるを使用しました。
チェック。 isInCart (IsInCart) のプロパティの値は、ターゲット要素にバインドします。 チェック ボックス要素を使用します。
クリックしてください。 saveData ユーザー DOM 要素をクリックすると、イベント ハンドラーのバインドされた JavaScript の関数 (saveData) を追加します。 DOM 要素での動作が入力ボタンの場合は、よく使われると の要素。
attr: {src:photoUrl、alt:名} DOM 要素の指定した属性は、ソース オブジェクトにバインドします。 多くの他の組み込みバインドのシナリオなど、img タグの src 属性をカバーしない場合使用。

ObservableArrays

前の例あなたのフィートウェットのノックアウトを得た今より実践的なまだまだ基礎の例階層データを移動する時間です。 ノックアウト (前の例のように) 単純なプロパティへのバインドを含むバインド、JavaScript の配列へのバインド、計算バインディングと (これは私は今後の記事でノックアウトに見ていきます) カスタム バインドの多くの種類がサポートされています。 ノックアウトする一覧を使用して製品オブジェクトの配列をバインドする方法を次に示します (表示図 4)。

Binding to an Observable Array
図 4 のような配列にバインド

オブジェクト グラフとデータ バインディングを扱うときは、すべてのデータとページを 1 つのオブジェクトに必要な機能をカプセル化すると便利です。 これは、多くの場合に、ViewModel として MVVM パターンから呼ばれます。 この例では、ビューは、HTML ページとは、DOM 要素です。 モデルは、製品の配列です。 ViewModel モデルのビューを接着剤; それを使用して、接着剤はノックアウトです。

製品の配列は、observableArray 関数を使用して設定されます。 これは XAML 技術 ObservableCollection に似ています。 製品のプロパティに項目が追加されるたびに、observableArray または配列から削除するため、ターゲット要素に通知して、項目を追加またはここに示すように、DOM からを削除します。

var showroomViewModel = {
  products: ko.observableArray()
};

ShowroomViewModel は、ターゲット要素にバインドされたデータが、ルート オブジェクトです。 それには、JSON をデータ サービスからなる製品の一覧が含まれます。 製品の一覧をロード関数で表示される、showroomViewModel.load 関数で図 5 (見つける、完全なソースとサンプル データこの例 03-observableArrays.html での) showroomViewModel オブジェクトを設定します、JavaScript の残りの部分と一緒に。 Load 関数は、サンプルの製品データをループし、Product 関数を使用して、observableArray にそれらを押す前に製品の新しいオブジェクトを作成します。

図 5 データへのバインドを定義します。

var photoPath = "/images/";
function Product () {
  this.id = ko.observable();
  this.salePrice = ko.observable();
  this.listPrice = ko.observable();
  this.rating = ko.observable();
  this.photo = ko.observable();
  this.itemNumber = ko.observable();
  this.description = ko.observable();
  this.photoUrl = ko.computed(function () {
    return photoPath + this.photo();
  }, this);
};
var showroomViewModel = {
  products: ko.observableArray()
};
showroomViewModel.load = function () {
  this.products([]); // reset
  $.each(data.Products, function (i, p) {
    showroomViewModel.products.push(new Product()
      .id(p.Id)
      .salePrice(p.SalePrice)
      .listPrice(p.ListPrice)
      .rating(p.Rating)
      .photo(p.Photo)
      .itemNumber(p.ItemNumber)
      .description(p.Description)
      );
  });
};
ko.applyBindings(showroomViewModel);

製品のプロパティすべて偏極量を使用して定義されていますが、彼らは必ずしも観測する必要はありません。 たとえば、これら場合は読み取り専用プレーンのプロパティをして可能性がある —、ソースが変更されたとき — ターゲットを更新すると期待されないまたはコンテナー全体を更新する必要があります。 ただし、プロパティを更新する必要がある場合に、ソース変更か注目すべき正しい選択ですし、DOM の編集します。

製品機能ノックアウト偏極量 (photoUrl) 以外としてのすべてのプロパティを定義します。 ノックアウト、データにバインドする場合、どのように多くの項目が現在データ バインドされるを表示する長さなどの使いやすいの標準機能をする製品配列プロパティがアクセスすることができます。

<span data-bind="text: products().length"></span>

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

製品の配列は、そのデータを DOM 要素には、匿名のテンプレートとして、リストを表示するため使用するバインドできます。 次の HTML は、ul タグを製品をバインドする foreach フロー制御のバインディングを使用することを示しています。

<ul data-bind="foreach:products">
  <li class="guitarListCompact">
    <div class="photoContainer">
      <img data-bind="visible: photoUrl, attr: { src: photoUrl }" 
        class="photoThumbnail"></img>
    </div>
    <div data-bind="text: salePrice"></div>
  </li>
</ul>

Ul タグ内の要素となる各製品にテンプレートを使用します。 Foreach の内部データ コンテキストも個々 の商品をルート オブジェクト showroomViewModel からを変更します。 これは、ために内部の DOM 要素を製品の photoUrl と salePrice のプロパティに直接バインドできます。

4 つの主要な制御のバインディングです。foreach、場合は、ifnot とします。 これらのコントロールのバインドでは、名前付きテンプレートを作成せず、制御フロー ロジックを宣言によって定義することができます。 場合、フロー制御のバインディングの truthy は、条件によって後にまたは ifnot バインドを評価する条件が false に続いている場合は、そのブロック内の内容はバインドし、ここのように表示。

<div data-bind="if:onSale">
  <span data-bind="text: salePrice"></span>
</div>

変更をバインドと何があなたをオブジェクトにデータ コンテキストを指定します。 これは、複数の親/子の関係または異なる ViewModels はページ内のオブジェクト グラフにダイビングするときに特に便利です。 たとえば、あるページにバインドされている、販売の ViewModel オブジェクトと子オブジェクトの顧客、販売員が場合、バインディングで、バインディングより読みやすく、簡単に維持するには、次のようにされる可能性があります。

<div data-bind="with:customer">
  <span data-bind="text: name"></span><br/>
  <span data-bind="text: orderTotal"></span>
</div>
<div data-bind="with:salesPerson">
  <span data-bind="text: employeeNum"></span><br/>
  <span data-bind="text: name"></span>
</div>

計算量

製品機能、photoUrl、特殊な計算プロパティとして定義することに気づいたことがあります。 ko.computed では、データ バインディング操作の値を評価するバインド関数を定義します。 計算プロパティは、その評価の変更を依存偏極量のときを自動的に更新します。 値を明確に、コンクリートの値のソース オブジェクトの表現ではない場合に特に役立ちます。 URL を作成する以外の別の一般的な例には、fullName プロパティの firstName と lastName プロパティを作成です。

(注: 以前のバージョンのノックアウト計算プロパティ dependentObservable として呼ばれます。 両方はノックアウト 2.0.0 の動作しますが、新しい計算関数を使用をお勧めします)。

計算プロパティ値とバインディングをアタッチするオブジェクトを表すオブジェクトを評価するための機能を受け入れます。 2 番目のパラメーターは JavaScript オブジェクト リテラルを参照する方法があるないために重要です。 図 5 、観測、依存の関数は写真のプロパティを取得することができます (これは、showroomViewModel を表す) このキーワードに渡されます。 こので渡される、写真関数が定義されているだろうし、評価は、予想される URL を生成する失敗します。

this.photoUrl = ko.computed(function () {
  return photoPath +  photo();  // photo() will be undefined
});

基本的なバインディング プロパティの理解

この列は、ノックアウト JavaScript ライブラリを使用してデータ バインディングを得た。 ノックアウトの最も重要な側面は、基本的なバインディング プロパティを理解することです。観測、observableArray と計算されました。 これらの偏極量と固体の分離パターンを使用して堅牢な HTML アプリケーションを作成できます。 より共通の組み込みバインドの種類を対象し、フロー制御のバインディングを示します。 ただし、ノックアウト多くの機能をサポートします。 次の時間、私は組み込みのバインドの詳細を説明します。

John Papa 、Microsoft の元のエバンジェ リスト、Silverlight と Windows の 8 チームが、彼は人気の Silverlight のテレビ番組のホストです。 彼は世界的に基調講演やセッションで、ビルド、ミックス、PDC、Tech•Ed、Visual Studio Live の発表している ! DevConnections イベント。パパも Visual Studio Magazine (パパの視点) の著者である Pluralsight のトレーニング ビデオのコラムニストであります。彼は Twitter の上に従う twitter.com/john_papa

この記事のレビュー、技術スタッフのおかげでに: Steve Sanderson