2017-05-10 7 views
1

私が理解していて分かりませんでしたか、それとも理解できていなくて、私はしなかったし、まだしない場合。私はKnockout.jsを理解しました。今はあまり確信していません。

私は、ユーザーが予定を予約できるようにするアプリを構築しています。

画面1:(確認と上を移動するためのオプションリスト、ボタン)の場所とサービスタイプを選択し

画面2:利用可能予定時刻を選択し

(テーブル、ボタンを確認し、上に移動します)画面3:

画面4(確認し、上に移動するには、テキスト入力、ボタン)の名前と連絡先情報を入力します(確認し、上に移動するユーザー、ボタンに尋ねてみた)確認コードを入力してください

画面5:表示確認コード

私はすべてが私のViewModelにあって、私のモデルに属しているものと私のViewModelに属しているものが分からないので、リファクタリングしています。私はちょうどモデルにselectedLocation(項目リストからユーザーピック)を置くが、私はそれを見ることでアクセスできるようにする必要があるので、私はこれをしなかった:

self.selectedLocation = ko.pureComputed({ 
    read: function() { 
     return self.model.selectedLocation(); 
    }, 
    write: function(value){ 
     self.model.selectedLocation(value); 
    } 
}); 

ちょうど狂気思われます。

これはViewModelにあるべきですか?モデルでselectedLocation変数を、ViewModelでcurrentlySelectedLocationを使用して、ユーザーがLocationとService Typeを確認したときにmodel.selectedLocationを更新する必要がありますか?

それぞれの画面にはそれぞれ独自のビューモデルが必要ですか?私は単一の.htmlファイルを使用して、ページからページに行くのではなく表示されているものを更新しています。

私は何らかの重要な情報を含めていないと確信しています。私はお詫び申し上げます。ご質問にお答えします。

ご協力いただければ幸いです。

+0

ノックアウトのモデルとビューモデルがぼやけます。あるパターンに固執することを心配しないでください。パターンはあなたを奉仕するために存在し、他の方法ではありません。私は、UIがviewmodel-yとされているかどうかを指示していることがわかります。私がpojsoを取得してUIに表示するだけであれば、それはモデルです。対話的なバインディングが必要なプロパティがある場合は、それをobservableに変換します。コレクションをプッシュまたはポップする必要はありませんか?それは配列です。 UIは応答する必要がありますか?それはobservableArrayです。 – Will

答えて

3

観測についてのクールなことは、あなただけの他のオブジェクトにそれらを使用することができるということです。

self.selectedLocation = self.model.selectedLocation; 

しかし、私はそれだけでmodel.selectedLocationに直接結合しても大丈夫ですことを示唆しています。ノックアウトでは、モデル/ビューモデルの区別は必要ありません。すべてがビューモデルです。

+0

ありがとう!私はmodel.selectedLocationに直接バインドすることにしました。 – spconrad

1

モデルとビューモデルを分けることをお勧めします。私が見ているのは、モデルはあなたが作業しているデータの表現であり、viewmodelはさまざまなモデルをまとめ、コントローラのような機能を追加してページのロジックを実行します(UIのやり取りの処理、データの取得、データバインディングなど)。あなたのモデルは単なるプロパティの束であり、モデルの生データからフォーマットされた表示テキストを提供するようなことをするいくつかのヘルパープロパティです。しかしモデルには実際のロジックはありません。モデルプロパティ自体に双方向データバインディングが必要な場合は、それらをKO観測として定義するだけです。

これをすべて1つのhtmlファイル(基本的にSPA)で実行したい場合、間違いなくこれをいくつかの「ビューモデル」に分割したいと思うでしょう。Knockoutは単一のviewmodelオブジェクトにのみバインディングを適用することができますが、KO観測可能なnレベルのJavascriptオブジェクトを入れ子にすることができ、KOはオブジェクトグラフに従うことができます(Michael Bestの回答に記載されています) 。これらのネストされた「ビューモデル」サブビューモデルを呼び出してみましょう。

アプリ全体を表すマスタービューモデルと、アプリのページあたり少なくとも1つのサブビューモデルを作成することをおすすめします。

<div data-bind="foreach: screen1ViewModel.locations"> 
    <!--Bind the click event to the viewmodel handler, and display the description of the location in the button--> 
    <button data-bind="click: $parent.locationSelected"><span data-bind="text: description"></span></button> 
</div> 

一つの最終:

var AppViewModel = function (screen1Vm, screen2Vm, ...) { 
    var self = this; 

    self.screen1ViewModel = screen1Vm; 
    self.screen2ViewModel = screen2Vm; 
    ... 
} 

var Screen1ViewModel = function() { 
    var self = this; 

    self.selectedLocation = ko.observable(null); //Initialize as null 
    self.locations = ko.observableArray([]); //assuming they're selecting from a list of Location objects. Initialize as empty array. 
    ... 
    //More logic to handle UI events, like a KO click event binding when one of the locations is selected, which is where self.selectedLocation would get set. Something like this 
    self.locationSelected = function (location) { 
     //When bound to a control inside a KO foreach context, the actual object in the KO observable array will be passed in. 
     self.selectedLocation(location); 
    } 
} 

var Location = function (description, city, state, ...) { 
    var self = this; 

    self.description = ko.observable(description); 
    self.city = ko.observable(city); 
    self.state = ko.observable(state); 
    ... 
} 

... 

var screen1Vm = new Screen1ViewModel(); 
var screen2Vm = new Screen2ViewModel(); 
... 
var myAppVm = new AppViewModel(screen1Vm, screen2Vm, ...) 
ko.applyBindings(myAppVm); 

は、その後、あなたがこのような何か(明らかにあなたがあなたのビューのために必要なものにDOM要素を変更)を見て、いくつかのHTMLを持っていると思います。だから、次のようになりますポイント。 1つのページでこれをすべてやっているので、できるだけKOテンプレートを使ってHTMLを整理し、各サブビューモデルを独自の.jsファイルに配置することをお勧めします。アプリ。

関連する問題