Я трачу часы, пытаясь заставить простой вызов событий работать правильно в моем приложении durandal/knockout.
Контекст
У меня есть список языков, которые пользователь может выбрать из окна выбора:
<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());
},
Проблема
- первый параметр "данные" не содержит выбранный элемент, но вместо этого содержит все элементы (на самом деле это полная модель текущего вида).
- Если 1. не работает, то это будет альтернативой, по крайней мере, получить новое значение из наблюдаемого 'selectedLanguage'. К сожалению, это всегда кажется старым. Поэтому всякий раз, когда я меняю опцию selectbox, я всегда получаю ранее выбранное значение.
Вопрос
Итак, вопрос в том, что я могу делать неправильно? Я уверен, что это нормально работает правильно, и я должен что-то пропускать где-то.
Я думал, что наконец понял, как работает нокаут, но теперь я столкнулся с следующей проблемой. Я был бы очень благодарен, если бы кто-нибудь мог мне помочь в этом.
EDIT [SOLVED]
Благодаря xdumaine, это (хорошее и простое) решение:
В моем шаблоне html я удалил событие change:
<select class="form-control select2"
data-bind="options:languages,
optionsText:'label',
optionsValue:'code',
value:app.selectedLanguage"></select>
В моей модели приложения App (которую я требую везде), теперь я подписываюсь на 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());
},
С уважением, Майкл