Knock-out changement de gestionnaire d'événements

Je suis passer des heures à essayer d'obtenir un simple événement de travail pour l'appel correctement dans mon durandal/knock-out app.

Contexte

J'ai une liste des langues que l'utilisateur peut sélectionner à partir d'un select case:

    <select class="form-control select2"
        data-bind="event: { change: app.languageChanged }, options:languages,
        optionsText:'label',
        optionsValue:'code',
        value:app.selectedLanguage"></select>

La propriété application.selectedLanguage est un ko.observables. Je sais que cela fonctionne parce que le bon élément sera pré-sélectionnés.

    this.selectedLanguage = ko.observable(options.defaultLanguage);

J'ai aussi un gestionnaire d'événements qui écoute les changements sur la boîte de sélection, afin que je puisse envoyer un message à d'autres parties de l'application qui a besoin d'être informé:

    languageChanged : function(data, event) {
        console.log(data);
        console.log(event);
        console.log(this.selectedLanguage());

        app.trigger('language:change', this.selectedLanguage());
    },

Le problème

  1. le premier paramètre "données" ne contient pas l'élément sélectionné, mais plutôt les contient tous les éléments (en fait, il semble être l'actuelle complète de la vue modèle).
  2. Si 1. ne fonctionne pas, alors il pourrait être une alternative pour au moins obtenir la nouvelle valeur de l'observable 'selectedLanguage'. Malheureusement, cela semble avoir toujours l'ancienne valeur. Donc à chaque fois que je change la selectbox option, j'ai toujours été précédemment sélectionné, la valeur.

Question

La question est donc: que pouvais-je fait de mal? Je suis sûr que cela fonctionne correctement et je dois manquer quelque chose quelque part.

Je pensais que j'avais enfin compris comment knock-out fonctionne, mais maintenant, je suis venu dans le prochain numéro. Je vous serais très reconnaissant si quelqu'un pouvait m'aider sur ce point.

MODIFIER [RÉSOLU]

Grâce à xdumaine, voici le (beau) solution:

Dans mon template html, j'ai enlevé le changement de l'événement:

    <select class="form-control select2"
        data-bind="options:languages,
        optionsText:'label',
        optionsValue:'code',
        value:app.selectedLanguage"></select>

Dans mon Appli vue-modèle (que j'ai besoin d'un peu partout), je vais maintenant vous abonner à la ko.observables au lieu d'écouter le gestionnaire d'événements:

    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;
});

Ce code a donc été supprimé et n'est plus nécessaire:

languageChanged : function(data, event) {
console.log(data);
console.log(event);
console.log(this.selectedLanguage());
app.trigger('language:change', this.selectedLanguage());
},

Meilleures salutations,
Michael

Cela pourrait peut-être aider : knockoutjs.com/documentation/unobtrusive-event-handling.html
Il est difficile de savoir ce que app est dans votre code. C'est qu'un durandal chose ou est-ce votre dernier?
Salut, c'est un mondial ViewModel que je passe via nécessitent dans toutes mes pages: define([ 'knock-out', 'myapp/myapp' ], function(ko, myapp) {. Je puis rendre disponible à la vue comme: return { app: myapp.app, ...}.
Michael, qui remonte à l'une des recommandations que j'ai faites: knock-out de la boite postale. Ryan Niemeyer a construit une grande fonctionnalité au-dessus de l'abonnement directement observables qui est juste comme facile à utiliser. Alors que nous utilisons postal.js pour notre client-side bus de message, nous ne vous direct abonnements pour interne notifications, et quand nous avons besoin d'obtenir que près de la métal.
Oui, merci. Je suppose que, dans la question que vous vous référez (stackoverflow.com/questions/22542051/...), j'ai été plus intéressé dans l'obtention de la langue-changement-événement "remarqué" dans les bons endroits. Il n'est pas à moi à ce moment-là que j'ai eu ce problème. Je pensais que la gestion réelle de l'événement fonctionnait bien, et à partir de là, c'était juste une question de faire passer le message. Ce matin, j'ai réalisé que ce n'était malheureusement pas le cas et j'ai pas très bien compris le concept de ko-abonnez-vous encore.

OriginalL'auteur michaeldd | 2014-03-21