Javascript 淘汰更改事件处理程序

Javascript 淘汰更改事件处理程序,javascript,knockout.js,durandal,Javascript,Knockout.js,Durandal,我花了几个小时试图让一个简单的事件调用在我的durandal/knockout应用程序中正常工作 上下文 我有一个语言列表,用户可以从选择框中选择: <select class="form-control select2" data-bind="event: { change: app.languageChanged }, options:languages, optionsText:'label', optionsValue:'co

我花了几个小时试图让一个简单的事件调用在我的durandal/knockout应用程序中正常工作

上下文

我有一个语言列表,用户可以从选择框中选择:

    <select class="form-control select2"
        data-bind="event: { change: app.languageChanged }, options:languages,
        optionsText:'label',
        optionsValue:'code',
        value:app.selectedLanguage"></select>
我还有一个事件处理程序,用于侦听选择框上的更改,以便我可以向需要通知的应用程序的其他部分发送消息:

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

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

  • 第一个参数“data”不包含所选项目,而是包含所有项目(实际上,它似乎是完整的当前视图模型)
  • 如果1。如果不起作用,那么至少可以从可观察的“selectedLanguage”中获取新值。不幸的是,这似乎总是有旧的价值。因此,每当我更改selectbox选项时,我总是得到以前选择的值
  • 问题

    所以问题是:我做错了什么?我确信这通常是正确的,我一定是遗漏了什么

    我以为我终于明白了淘汰赛是如何运作的,但现在我遇到了下一个问题。如果有人能在这方面帮助我,我将非常感激

    编辑[已解决]

    多亏了xdumaine,以下是(漂亮而简单)的解决方案:

    在我的html模板中,我删除了更改事件:

        <select class="form-control select2"
            data-bind="options:languages,
            optionsText:'label',
            optionsValue:'code',
            value:app.selectedLanguage"></select>
    
    因此,此代码已被删除,不再需要:

    languageChanged : function(data, event) {
        console.log(data);
        console.log(event);
        console.log(this.selectedLanguage());
    
        app.trigger('language:change', this.selectedLanguage());
    },
    
    致以最良好的祝愿,
    Michael

    为什么要绑定到select change事件,而不只是订阅selectedLanguage

    var self = this;
    self.selectedLanguage = ko.observable();
    self.selectedLangauge.subscribe(function(newValue) {
        console.log(newValue);
        app.trigger('language:change', newValue);
    });
    
    如果您想像现在这样做,请知道:knockout中的事件绑定总是将对viewModel的引用作为第一个参数,将事件数据作为第二个参数,因此您可能必须检查事件以获取目标并提取值(如果您这样做的话)。2不起作用的原因是您的更改事件在通知淘汰可观察对象之前触发,因此您会遇到时间问题。这在不同的浏览器中可能有不同的行为


    我建议尽可能坚持使用可观察订阅,而不是使用DOM事件。

    也许这会有所帮助:不清楚代码中的
    app
    是什么。这是durandal的东西还是你的viewModel?嗨,这是一个全局viewModel,我通过require将其传递到我的所有页面:define(['knockout','myapp/myapp'],function(ko,myapp){。然后我将其提供给视图,如下所示:return{app:myapp.app,…}@michaeldd Michael,这可以追溯到我提出的一个建议:击倒邮箱。Ryan Niemeyer在直接订阅可观察对象的基础上构建了一些非常好的功能,这同样易于使用。虽然我们在客户端消息总线上使用postal.js,但我们可以在需要时直接订阅内部通知是的,谢谢。我想在你提到的问题()中,我更关心的是让语言变化事件被“注意到”在正确的地方。当时我没有想到我有这个问题。我认为事件的实际处理工作正常,从那时起,只是传递信息的问题。今天早上我意识到不幸的是情况并非如此,我还不太理解淘汰订阅的概念。谢谢,我会尝试。我还不知道所有的可能性,所以没有特别的理由这样做。你的解决方案感觉更好。我会尝试一下,让你知道这是否解决了问题。谢谢,这非常有效。我会编辑我的初始帖子,因为这可能对其他人有用,并且你的代码有一些小的拼写错误:-).再次感谢!
    languageChanged : function(data, event) {
        console.log(data);
        console.log(event);
        console.log(this.selectedLanguage());
    
        app.trigger('language:change', this.selectedLanguage());
    },
    
    var self = this;
    self.selectedLanguage = ko.observable();
    self.selectedLangauge.subscribe(function(newValue) {
        console.log(newValue);
        app.trigger('language:change', newValue);
    });