简体   繁体   English

淘汰赛更改事件处理程序

[英]Knockout change event-handler

I am spending hours trying to get a simple event call working correctly in my durandal/knockout app. 我花了好几个小时试图让我的durandal / knockout应用程序中的一个简单的事件调用正常工作。

Context 上下文

I have a list of languages that that the user can select from a select-box: 我有一个用户可以从选择框中选择的语言列表:

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

The property app.selectedLanguage is a ko.observable. app.selectedLanguage属性是一个ko.observable。 I know that this works because the correct item gets pre-selected. 我知道这是有效的,因为正确的项目被预选。

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

I also have an event-handler which listens for changes on that select box, so that I can send a message to other parts of the application that need to be informed: 我还有一个事件处理程序,它监听该选择框上的更改,以便我可以向应用程序的其他需要通知的部分发送消息:

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

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

The problem 问题

  1. the first parameter 'data' does not contain the selected item, but instead contains all items (actually, it seems to be the complete current view-model). 第一个参数'data'不包含所选项,而是包含所有项(实际上,它似乎是完整的当前视图模型)。
  2. If 1. does not work, then it would be an alternative to at least get hold of the new value from the observable 'selectedLanguage'. 如果1.不起作用,那么它至少可以从可观察的“selectedLanguage”中获取新值。 Unfortunately that always seems to have the old value. 不幸的是,似乎总是有旧的价值。 So whenever I change the selectbox option, I always get the previously selected value. 所以每当我更改selectbox选项时,我总是得到之前选择的值。

Question

So the question is: what could I be doing wrong? 所以问题是: 我能做错什么? I am sure that this normally works correctly and I must be missing something somewhere. 我相信这通常是正常的,我必须在某处遗漏某些东西。

I thought I had finally understood how knockout works, but now I have come across the next issue. 我以为我终于明白淘汰赛是如何运作的,但现在我遇到了下一个问题。 I would be very grateful if someone could help me on this. 如果有人可以帮助我,我将非常感激。

EDIT [SOLVED] 编辑[求助]

Thanks to xdumaine, here is the (nice and simple) solution: 感谢xdumaine,这是(好的和简单的)解决方案:

In my html template, I removed the change-event: 在我的html模板中,我删除了更改事件:

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

In my App view-model (that I require everywhere), I now subscribe to the ko.observable instead of listening to the event-handler: 在我的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;
    });

This code has therefore been removed and is no longer needed: 因此,此代码已被删除,不再需要:

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

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

Best regards, Michael 最好的问候,迈克尔

Why bind to the select change event instead of just subscribing to the selectedLanguage? 为什么绑定到select change事件而不是仅仅订阅selectedLanguage?

var self = this;
self.selectedLanguage = ko.observable();
self.selectedLangauge.subscribe(function(newValue) {
    console.log(newValue);
    app.trigger('language:change', newValue);
});

If you want to do it like you have it, know this: event bindings in knockout always get a reference to the viewModel as the first parameter, and the event data as the second, so you could would have to inspect the event to get the target and extract the value if you're doing it that way. 如果你想像你拥有它一样,知道这一点:在knockout中的事件绑定总是得到对viewModel的引用作为第一个参数,事件数据作为第二个参数,所以你可能必须检查事件以获得如果你这样做,就瞄准并提取价值。 The reason 2 is not working is that your change event is firing before the knockout observable is notified, so you get timing issues. 原因2不起作用的是您的更改事件在通知淘汰观察结果之前触发,因此您会遇到时间问题。 This could have different behavior in different browsers. 这可能在不同的浏览器中有不同的行为。

I'd recommend sticking to observable subscriptions, instead of using DOM events, whenever possible. 我建议尽可能坚持使用可观察的订阅,而不是使用DOM事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM