繁体   English   中英

选择更改事件在绑定期间触发

[英]select change event fires during binding

我正在我的 asp.net mvc 5 应用程序中使用knockoutjs 构建一个多步骤表单。

问题是,在绑定期间,我的下拉列表的更改事件正在触发。 类似于这里报告的这个问题。

我已经尝试了上面帖子中建议的所有内容,但该事件仍然触发了两次。

 <div class="row">
            <div class="col-md-4">
                <div class="form-group">
                    @Html.LabelFor(model => model.Step1.Country, new { @class = "control-label" })
                    @Html.DropDownListFor(model => model.Step1.Country, Model.Step1.Countries, new { @class = "select-country", @style = "width: 100%;", data_bind = "value: Model.Step1.Country" })
                </div>
            </div>
            <div class="col-md-4">
                <div class="form-group">
                    @Html.LabelFor(model => model.Step1.State, new { @class = "control-label" })
                    @Html.DropDownListFor(model => model.Step1.State, Model.Step1.States, new { @style = "width: 100%;", data_bind = "value: Model.Step1.State" })
                </div>
            </div>
            <div class="col-md-4">
                <div class="form-group">
                    @Html.LabelFor(model => model.Step1.City, new { @class = "control-label" })
                    @Html.TextBoxFor(model => model.Step1.City, new { maxlength = "50", @class = "form-control", data_bind = "value: Model.Step1.City" })
                </div>
            </div>
        </div>

向导插件:

(function ($) {
$.fn.Wizard = function (options) {

    //Set the form of the current wizard
    var $form = $("#" + options.formId);

    var ViewModel = function (d, m) {
        var self = this;

        self.Model = ko.mapping.fromJS(d, m);

        self.Model.GeneralErrors = ko.computed(function () {
            return ko.utils.arrayFilter(self.Model.Errors(), function (item) {
                return !!item.MemberName;
            });
        });

        self.Model.Step1.Country.subscribe(function (value) {
            alert(value);
            console.log(value);
        });

        self.SelectionChanged = function (element) {

        }

    }

    var vm = new ViewModel(options.model, options.mapping);

    ko.applyBindings(vm, this[0]);

    vm.UpdateOnChange = true;

    return this;
    };
}(jQuery));

 <script type="text/javascript">
    $(function () {
        $("#WizardWrapper").Wizard({
            formId: "WizardForm",
            model: @(Html.Raw(Json.Encode(Model))),
            url: "/DataCollection/@HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString()/",
            mapping: {
                create: function (options){
                    var m = ko.mapping.fromJS(options.data);
                    return m;
                }
            }
        });
    });
</script>

有谁知道我该如何解决这个问题?

感谢用户3297291,

谢谢,添加 valueAllowUnset 会在绑定时停止事件触发,并在进行选择时触发。

但是,只有一个问题,单击保存时回发期间再次触发该事件。 该事件再次被触发

 ko.mapping.fromJS(data, self.Model);

在下面的ajax帖子中。

保存事件:

            self.Next = function (element) {
            var validator = $(element).closest("form").validate();

            if ($(element).closest("form").valid()) {
               $.ajax({
                    url: options.url + action,
                    type: 'POST',
                    dataType: 'json',
                    contentType: 'application/json',
                    data: ko.toJSON(self.Model),
                    success: function (data) {
                        self.UpdateOnChange = false;
                        ko.mapping.fromJS(data, self.Model);
                        self.UpdateOnChange = true;
                    },
                    error: function (jqXHR, textStatus, errorThrown) {

                    }
                });
            } else {
                validator.focusInvalid();
            }
        }

按钮:

<input data-bind="event: { click: Next.bind($data, $element) }" type="submit" class="btn btn-default btn-prev btn-sky" value="Next" />

更新:

为了解决更新国家/地区后订阅再次触发的问题,我使用了此解决方案并进行了一些更改。

self.dirty = ko.observable(false);
        self.selectedCountry = ko.observable();

        self.dirtyCalculations = ko.computed(function () {
            var value = self.Model.Step1.Country();

            if (value == self.selectedCountry()) {
                self.selectedCountry(null);
                self.dirty(false);
            } else {
                self.selectedCountry(value);
                self.dirty(true);
            }
        });

self.Model.Step1.Country.subscribe(function (value) {
            if (value != undefined && self.dirty()) {
                $.ajax({
                    url: options.url + "GetState",
                    type: 'POST',
                    dataType: 'json',
                    contentType: 'application/json',
                    data: ko.toJSON(self.Model),
                    traditional: true,
                    success: function (data) {
                        self.UpdateOnChange = false;
                        ko.mapping.fromJS(data, self.Model);
                        self.UpdateOnChange = true;
                    }
                });
            } else {
                self.resetDirtyFlag();
            }
        });

简单回答:您可以(错误?)使用valueAllowUnset绑定。

 var VM = function(initial) { this.selection = ko.observable(initial); this.updateCount = ko.observable(0); this.selection.subscribe(function() { this.updateCount(this.updateCount() + 1); }, this); } ko.applyBindings(new VM(1), document.querySelector(".example1")); ko.applyBindings(new VM(2), document.querySelector(".example2"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div class="example1"> <h1>with valueAllowUnset</h1> <select name="" id="" data-bind="value: selection, valueAllowUnset: true"> <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> </select> <div> Updates: <span data-bind="text: updateCount"></span> </div> </div> <div class="example2"> <h1>without valueAllowUnset</h1> <select name="" id="" data-bind="value: selection"> <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> </select> <div> Updates: <span data-bind="text: updateCount"></span> </div> </div>

替代解决方案:我建议使用options绑定来通过淘汰赛而不是 MVC 呈现您的选项。 它使调试客户端变得更容易一些。 但这可能是个人喜好。

暂无
暂无

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

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