javascript – Knockout更改事件处理程序

我花了几个小时尝试在我的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());
    },

问题

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

所以问题是:我该怎么做错了?我确信这通常正常工作,我必须在某处丢失某物.

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

编辑[解决]

感谢xdumaine,这是(好的和简单的)解决方案:

在我的html模板中,我删除了change-event:

<select class="form-control select2"
        data-bind="options:languages,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());
},

最好的祝福,
迈克尔

解决方法

为什么绑定到选择更改事件,而不是只订阅selectedLanguage?
var self = this;
self.selectedLanguage = ko.observable();
self.selectedLangauge.subscribe(function(newValue) {
    console.log(newValue);
    app.trigger('language:change',newValue);
});

如果你想像这样做,知道这一点:事件绑定在敲除总是得到一个参考的viewmodel作为第一个参数,事件数据作为第二个,所以你可能必须检查事件得到如果您这样做,则定位并提取值.原因2不工作是您的更改事件在通知敲门声之前触发,因此您可以获得时间安排问题.这可能在不同的浏览器中有不同的行为.

我建议坚持使用可观察的订阅,而不是使用DOM事件.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...