销毁更改事件处理程序

Knockout change event-handler

本文关键字:事件处理 程序      更新时间:2023-09-26

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

<<p> 上下文/strong>

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

    <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. 第一个参数'data'不包含所选项,而是包含所有项(实际上,它似乎是完整的当前视图模型)。如果1
  2. 。不工作,那么它将是一个替代方案,至少从可观察对象'selectedLanguage'中获取新值。不幸的是,这似乎总是有旧的价值。所以无论何时我改变selectbox选项,我总是得到之前选择的值。

所以问题是:我做错了什么?我确信这正常工作,我一定是错过了什么地方。

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

编辑(解决)

感谢xdumaine,这里是(漂亮而简单的)解决方案:

在我的html模板中,我删除了change-event:
    <select class="form-control select2"
        data-bind="options:languages,
        optionsText:'label',
        optionsValue:'code',
        value:app.selectedLanguage"></select>

在我的App视图模型中(我到处都需要),我现在订阅ko。观察对象,而不是监听事件处理程序:

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

最诚挚的问候,迈克尔。

为什么绑定到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不能工作是因为您的更改事件在通知knockout可观察对象之前触发,因此您会遇到时间问题。这在不同的浏览器中可能有不同的行为。

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