[解決済み】オブジェクトリテラルとして宣言されたノックアウトビューモデルと関数の違いについて
質問
Knockout jsでは、View Modelsはどちらかで宣言されていますね。
var viewModel = {
firstname: ko.observable("Bob")
};
ko.applyBindings(viewModel );
または
var viewModel = function() {
this.firstname= ko.observable("Bob");
};
ko.applyBindings(new viewModel ());
両者の違いがあるとすれば、それは何でしょうか?
確かに この議論 をノックアウトjsのgoogleグループに投稿しましたが、満足のいく回答は得られませんでした。
例えば、あるデータでモデルを初期化したい場合、その理由はわかります。
var viewModel = function(person) {
this.firstname= ko.observable(person.firstname);
};
var person = ... ;
ko.applyBindings(new viewModel(person));
でも、そうでないなら、どのスタイルを選んでもいいのでしょうか?
どのように解決するのですか?
ビューモデルを定義するために関数を使用することには、いくつかの利点があります。
の値にすぐにアクセスできることが主な利点です。
this
は、作成されるインスタンスに等しい。 つまり、以下のようなことができます。
var ViewModel = function(first, last) {
this.first = ko.observable(first);
this.last = ko.observable(last);
this.full = ko.computed(function() {
return this.first() + " " + this.last();
}, this);
};
つまり、計算された観測値は
this
別のスコープから呼び出されたとしても、です。
オブジェクト・リテラルだと、そうせざるを得ない。
var viewModel = {
first: ko.observable("Bob"),
last: ko.observable("Smith"),
};
viewModel.full = ko.computed(function() {
return this.first() + " " + this.last();
}, viewModel);
その場合は
viewModel
は計算されたobservableの中で直接評価されますが、(デフォルトでは)すぐに評価されるので、オブジェクトリテラルの中で定義することはできません。
viewModel
は、オブジェクト・リテラルを閉じた後でないと定義されません。 多くの人は、ビューモデルの作成が1回の呼び出しでカプセル化されないことを嫌がります。
もう一つのパターンとして
this
が常に適切な値になるように、関数内の変数に
this
を作成し、それを代わりに使用します。 これは、次のようなものです。
var ViewModel = function() {
var self = this;
this.items = ko.observableArray();
this.removeItem = function(item) {
self.items.remove(item);
}
};
さて、個々のアイテムのスコープで、以下のように呼び出したとします。
$root.removeItem
の値は
this
は、実際にはそのレベルでバインドされているデータ (これはアイテムになります) になります。 この場合、self を使用することで、ビューモデル全体から削除されていることを確認することができます。
もう一つの方法は
bind
は、モダンブラウザでサポートされており、サポートされていない場合は、KOによって追加されます。 その場合、次のようになります。
var ViewModel = function() {
this.items = ko.observableArray();
this.removeItem = function(item) {
this.items.remove(item);
}.bind(this);
};
このトピックにはもっと多くのことが語られ、多くのパターン(moduleパターンやexparing moduleパターンなど)がありますが、基本的に関数を使用すると、オブジェクトの生成方法をより柔軟に制御でき、インスタンスのプライベート変数を参照することが可能になります。
関連
-
fetch ネットワークリクエストラッパーの説明例
-
元のイベントが実行されなかった後に要素を追加するためのjQueryソリューション
-
[解決済み】event.stopPropagationとevent.preventDefaultの違いは何ですか?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] Bowerとnpmの違いは何ですか?
-
[解決済み] JavaScriptのnullとundefinedの違いは何ですか?
-
[解決済み] substrとsubstringの違いは何ですか?
-
[解決済み] nullはなぜオブジェクトなのか、nullとundefinedの違いは何ですか?
-
[解決済み] オブジェクトリテラル/イニシャライザーの自己参照
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vue+ElementUIによる大規模なフォームの処理例
-
vue for 登録ページ効果 vue for sms 認証コードログイン
-
Vueの一般的な組み込みディレクティブの説明
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
[解決済み】「X-Frame-Options」を「SAMEORIGIN」に設定したため、フレームでの表示を拒否された。
-
[解決済み】JavaScriptエラー(Uncaught SyntaxError: Unexpected end of input)
-
[解決済み】ExpressJS - throw er Unhandled errorイベント
-
[解決済み】JavaScriptでインラインIF文の書き方は?
-
[解決済み】 env: node: macにそのようなファイルやディレクトリはありません
-
Uncaught TypeError: null のプロパティ 'offsetHeight' を読み取れませんでした。