デュランダル/ノックアウトアプリで簡単なイベントコールを正しく機能させるために何時間も費やしています。
コンテキスト
ユーザーが選択ボックスから選択できる言語のリストがあります。
<select class="form-control select2"
data-bind="event: { change: app.languageChanged }, options:languages,
optionsText:'label',
optionsValue:'code',
value:app.selectedLanguage"></select>
プロパティapp.selectedLanguageはko.observableです。正しいアイテムが事前に選択されているため、これが機能することはわかっています。
this.selectedLanguage = ko.observable(options.defaultLanguage);
また、その選択ボックスの変更をリッスンするイベントハンドラーがあるので、通知が必要なアプリケーションの他の部分にメッセージを送信できます。
languageChanged : function(data, event) {
console.log(data);
console.log(event);
console.log(this.selectedLanguage());
app.trigger('language:change', this.selectedLanguage());
},
問題
質問
したがって、質問は次のとおりです。何が間違っている可能性がありますか?これは正常に機能し、どこかに何かが欠けているに違いありません。
ノックアウトの仕組みはようやく理解できたと思いましたが、次の問題に出くわしました。誰かがこれについて私を助けてくれたらとてもありがたいです。
編集[解決済み]
Xdumaineのおかげで、これが(素晴らしくシンプルな)解決策です:
私のhtmlテンプレートで、change-eventを削除しました。
<select class="form-control select2"
data-bind="options:languages,
optionsText:'label',
optionsValue:'code',
value:app.selectedLanguage"></select>
私のアプリビューモデル(どこでも必要です)では、イベントハンドラーをリッスンする代わりに、ko.observableをサブスクライブします。
define([ 'durandal/app', 'underscore', 'knockout', 'myapp/myapp' ], function(app, _, ko, myapp) {
"use strict";
function App(options) {
if (!(this instanceof App)) {
throw new TypeError("App constructor cannot be called as a function.");
}
this.options = options || {};
// Set the initial language.
this.selectedLanguage = ko.observable(options.defaultLanguage);
// *** Subscribes to the observable ***
this.selectedLanguage.subscribe(function(newValue) {
console.log(newValue);
app.trigger('language:change', newValue);
});
_.bindAll(this, 'getSelectedLanguage');
}
App.prototype = {
constructor : App,
getSelectedLanguage : function() {
return this.selectedLanguage();
}
}
return App;
});
したがって、このコードは削除され、不要になりました。
languageChanged : function(data, event) {
console.log(data);
console.log(event);
console.log(this.selectedLanguage());
app.trigger('language:change', this.selectedLanguage());
},
よろしく、マイケル
SelectedLanguageにサブスクライブするだけでなく、select changeイベントにバインドするのはなぜですか?
var self = this;
self.selectedLanguage = ko.observable();
self.selectedLangauge.subscribe(function(newValue) {
console.log(newValue);
app.trigger('language:change', newValue);
});
思い通りにやりたい場合は、次のことを知っておいてください。ノックアウトのイベントバインディングは、常に最初のパラメーターとしてviewModelへの参照を取得し、2番目のパラメーターとしてイベントデータを取得するため、イベントを検査して取得する必要があります。そのようにしている場合は、値をターゲットにして抽出します。 2が機能しない理由は、ノックアウトオブザーバブルが通知される前に変更イベントが発生しているため、タイミングの問題が発生するためです。これは、ブラウザによって動作が異なる可能性があります。
可能な限り、DOMイベントを使用するのではなく、監視可能なサブスクリプションに固執することをお勧めします。