淘汰赛复选框更改事件将旧值(Knockout checkbox change event sends

2019-07-30 05:24发布

我在“检查”以淘汰赛的问题结合。 看来,“变”的事件在复选框返回旧值,它被更新之前(所以如果它是未选中它会返回false)。 我不认为我可以订阅的价值,因为我把它里面的对象。

<tbody data-bind="foreach: Categories">
                <tr>
                    <td><input type="checkbox" data-bind="checked: ShowOpened, event: { change: $root.CategoryChange }" /></td>
                </tr>
            </tbody>
<script type="text/javascript">
var Category = function (Id, Name, Order, ShowOpened) {
    this.Id = Id;
    this.Name = Name;
    this.Order = Order;
    this.ShowOpened = ShowOpened;
    this.IsUpdated = ko.observable(false);

    this.OldOrder = Order;
    this.OldShowOpened = ShowOpened;
};
var ViewModel = {
    Categories: ko.observableArray([]),
    CategoryChange: function(pCategory) {
        if(pCategory.Order != pCategory.OldOrder || pCategory.ShowOpened != pCategory.OldShowOpened)
            pCategory.IsUpdated(true);
        else
            pCategory.IsUpdated(false);
    }
};
ko.applyBindings(ViewModel);
</script>

因此,在这个例子中,我ShowOpened复选框,可以触发CategoryChange方法,将改变内部对象的变量(即我需要后来知道是什么更新的对象)。 但是,当chechbox改变它总是发出的旧值,触发方法,然后更改数值。 有没有什么办法解决这一问题?

Answer 1:

既然你坚持上指出,缺乏ko.observables不是问题,我看着它接近。 看来,你是正确的! 该change被设置实际值之前触发事件。 我怕我不知道这样做的原因。

但有一个简单的方法来解决这个问题:只是改变change事件click事件:

<input type="checkbox" data-bind="checked: ShowOpened, click: $root.CategoryChange" />

请记住,你必须明确提出return true; 在结束click事件处理程序。 否则,新的值将不会被设置为复选框。

如果你不希望使用click事件,那么你可以做它的其他方式。 订阅的变化ShowOpened

this.ShowOpened = ko.observable(ShowOpened);
this.ShowOpened.subscribe(function(newValue) {
    /* Do something when ShowOpened changes.
       newValue variable holds the new value, obviously. :) */
});


Answer 2:

尝试使用subscribe的事件绑定来代替。 这应该现在的工作

<table>
    <tbody data-bind="foreach: Categories">
        <tr>
            <td><input type="checkbox" data-bind="checked: ShowOpened" /></td>
        </tr>
    </tbody>
<table>

var Category = function (Id, Name, Order, ShowOpened) {
    this.Id = Id;
    this.Name = Name;
    this.Order = Order;
    this.ShowOpened = ko.observable(ShowOpened);
    this.IsUpdated = false;

    this.OldOrder = Order;
    this.OldShowOpened = ShowOpened;

    this.ShowOpened.subscribe(function (newShowOpened) {
        if(this.Order != this.OldOrder || this.ShowOpened() != this.OldShowOpened)
            this.IsUpdated = true;
        else
            this.IsUpdated = false;
    }, this);
};
var ViewModel = {
    Categories: ko.observableArray([])
};
ko.applyBindings(ViewModel);

或作为替代(在我看来更好的解决方案),可以使用dependentObservable ,现在所谓的computed 。 下面是它会是什么样子

<table>
    <tbody data-bind="foreach: Categories">
        <tr>
            <td>
                <input type="checkbox" data-bind="checked: ShowOpened" />
                <span data-bind="text: IsUpdated"></span>
            </td>
        </tr>
    </tbody>
</table>
var Category = function (Id, Name, Order, ShowOpened) {
    this.Id = Id;
    this.Name = Name;
    this.Order = Order;
    this.ShowOpened = ko.observable(ShowOpened);
    this.OldOrder = Order;
    this.OldShowOpened = ShowOpened;
    this.IsUpdated = ko.computed(function () {
        return this.Order != this.OldOrder || this.ShowOpened() != this.OldShowOpened;
    }, this);
};
var ViewModel = {
    Categories: ko.observableArray([])
};
ko.applyBindings(ViewModel);


Answer 3:

我也有这个问题,但我不能使用订阅解决方案,因为我已经订购了相同的字段,可以重置价值Ajax请求。 然后,该代码会留在一个循环,当你改变了它。 因此,我增加了以下解决方法(它的丑陋,但它的工作原理)。

$("input[type='radio'], input[type='checkbox']", element).on("change", function (e, data) {
    setTimeout(function () {
        $(this).trigger("afterChange", data);
    }.bind(this), 10);
}); 

然后就不是听我的变化会听改动后的事件。

<div data-bind="foreach: answerList">
    <input type="checkbox" data-bind="event: { afterChange: $root.sendSelectedAnswer($data) }"/>
</div>

我知道它不是最好的解决办法,但在我的情况下,我没有其他选择。



文章来源: Knockout checkbox change event sends old value