【问题标题】:Uncaught TypeError: Unable to process binding "if" with knockout未捕获的类型错误:无法通过淘汰处理绑定“if”
【发布时间】:2021-04-29 12:07:43
【问题描述】:

我只是想创建一些复选框和输入,以便从数据库中获取数据并在编辑后将其保存回数据库。但我收到以下错误:

未捕获的类型错误:无法处理绑定“if: function(){return $root.editAlarmValues }” 消息:无法处理绑定“启用:function(){return $root.editAlarmValues().setAlarmValues() }” 消息:$root.editAlarmValues(...).setAlarmValues 不是函数

我不确定我做错了什么。我在控制台中检查,值被正确映射到数组,但它们似乎没有绑定到视图。任何帮助将不胜感激!

代码如下:

        <!--ko if: $root.editAlarmValues -->
       
            <div class="row">
                <div class="col-md-6">
                    <input type="checkbox" data-bind="iCheck: $root.editAlarmValues().setAlarmValues" class="large-check"/>
                </div>
            </div>

            <div class="row">
                <div class="col-md-5 form-inline">
                    <input type="checkbox" data-bind="iCheck: $root.editAlarmValues().setOutputCurrentPPLowValue, enable: $root.editAlarmValues().setAlarmValues()" class="large-check"/>
                            <input type="text" id="OutputCurrentPPLowValue" data-bind="value: $root.editAlarmValues().outputCurrentPPLowValue, enable: $root.editAlarmValues().setOutputCurrentPPLowValue()" class="form-control" maxlength="30" />
                 </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <div class="pull-right">

                        <button type="button" class="btn btn-primary btn-flat" data-bind="event: {click: $root.editSave}">Save</button>
                    </div>
                </div>
            </div>

            <!-- /ko -->

和脚本:

 var AlarmsViewModel = function (wellID) {

        function EditAlarms(setAlarmValues, setOutputCurrentPPLowValue, outputCurrentPPLowValue) {
            var self = this;
            self.setAlarmValues = ko.observable(setAlarmValues);
            self.setOutputCurrentPPLowValue = ko.observable(setOutputCurrentPPLowValue);
            self.outputCurrentPPLowValue = ko.observable(outputCurrentPPLowValue);
        }

        var self = this;
        self.wellID = ko.observable(wellID);
        self.editAlarmValues = ko.observableArray(); 
     
        self.init = function () {
            self.editAlarmInit();
        };

        self.editAlarmInit = function () {
            APIHelper.getData("/api/alarmapi/EditAlarms?wellID=" + self.wellID(), self.editAlarmsCallback, "");
        };

        self.editAlarmsCallback = function (data) {
            //Map results
            var temp = $.map(data.result, function (item) {
                return new EditAlarms(item.setAlarmValues, item.setOutputCurrentPPLowValue, item.outputCurrentPPLowValue);
            });
            self.editAlarmValues(temp);                
        };

        self.editSave = function () {
            var jsonData = ko.toJSON(self.editAlarmValues);        
            APIHelper.postData("/api/alarmapi/EditAlarmsPost", jsonData);
        };

        self.init();
    };

    var wellID = @ViewBag.WellID;
   
    ko.bindingHandlers.iCheck = {
        init: function (el, valueAccessor) {
            var observable = valueAccessor();
            $(el).on("ifChanged", function () {
                observable(this.checked);
            });
        },

        update: function (el, valueAccessor) {
            var val = ko.utils.unwrapObservable(valueAccessor());
            if (val) {
                $(el).iCheck('check');
            } else {
                $(el).iCheck('uncheck');
            }
        }
    };


    var vm = new AlarmsViewModel(wellID);
    ko.applyBindings(vm);

【问题讨论】:

    标签: javascript arrays knockout.js


    【解决方案1】:

    您不需要&lt;!-- ko if: editAlarmValues --&gt;,您需要&lt;!-- ko foreach: editAlarmValues --&gt;foreach在目标数组为空时不会运行,所以它基本上实现了相同的功能。

    foreach 内部,绑定上下文是有问题的EditAlarms 对象,因此您应该直接引用它的属性(iCheck: setOutputCurrentPPLowValue 而不是iCheck: $root.editAlarmValues().setOutputCurrentPPLowValue)。

    还要考虑您的命名。 EditAlarms 不是单个对象的好名字。前缀set... 应该是指设置某些东西的方法。在这种情况下,它只是一个可观察的属性。 setAlarmValues 应该被称为alarmValues,因为它不是一个数组,它可能实际上应该被称为alarmValue。以此类推。

    <!-- ko foreach: editAlarmValues -->
    <div class="row">
        <div class="col-md-6">
            <input type="checkbox" data-bind="iCheck: setAlarmValues" class="large-check">
        </div>
    </div>
    <div class="row">
        <div class="col-md-5 form-inline">
            <input type="checkbox" class="large-check" data-bind="
                iCheck: setOutputCurrentPPLowValue,
                enable: setAlarmValues
            ">
            <input type="text" id="OutputCurrentPPLowValue" class="form-control" maxlength="30" data-bind="
                value: outputCurrentPPLowValue,
                enable: setOutputCurrentPPLowValue
            ">
         </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <div class="pull-right">
                <button type="button" class="btn btn-primary btn-flat" data-bind="click: $root.editSave">Save</button>
            </div>
        </div>
    </div>
    <!-- /ko -->
    

    修改后的 JS 代码(将绑定处理程序定义移到顶部,不要嵌套视图模型)

    ko.bindingHandlers.iCheck = {
        init: function (el, valueAccessor) {
            var observable = valueAccessor();
            $(el).on("ifChanged", function () {
                observable(this.checked);
            });
        },
        update: function (el, valueAccessor) {
            var val = ko.unwap(valueAccessor());
            $(el).iCheck(val ? 'check' : 'uncheck');
        }
    };
    
    function EditAlarms(setAlarmValues, setOutputCurrentPPLowValue, outputCurrentPPLowValue) {
        this.setAlarmValues = ko.observable(setAlarmValues);
        this.setOutputCurrentPPLowValue = ko.observable(setOutputCurrentPPLowValue);
        this.outputCurrentPPLowValue = ko.observable(outputCurrentPPLowValue);
    }
    
    function AlarmsViewModel(wellID) {
        var self = this;
    
        self.wellID = ko.observable(wellID);
        self.editAlarmValues = ko.observableArray();
    
        self.editAlarmInit = function () {
            APIHelper.getData("/api/alarmapi/EditAlarms?wellID=" + self.wellID(), function (data) {
                var alarms = data.result.map(item => new EditAlarms(
                    item.setAlarmValues,
                    item.setOutputCurrentPPLowValue,
                    item.outputCurrentPPLowValue
                ));
                self.editAlarmValues(alarms);
            });
        };
        self.editSave = function () {
            APIHelper.postData("/api/alarmapi/EditAlarmsPost", ko.toJSON(self.editAlarmValues));
        };
    
        self.editAlarmInit();
    }
    
    var vm = new AlarmsViewModel(@ViewBag.WellID);
    ko.applyBindings(vm);
    

    【讨论】:

    • 谢谢!这有助于解决相关错误。我不得不将绑定处理程序修改为update: function (el, valueAccessor) { var val = ko.utils.unwrapObservable(valueAccessor()); $(el).iCheck(val ? 'check' : 'uncheck'); },因为我在展开时遇到错误,这清除了该错误。现在这些值是绑定的,但它们不会按预期更改启用,所以当我检查 setAlarmValues 时,以下复选框保持禁用状态。
    • @RalucaMicu 您使用的是哪个版本的淘汰赛? ko.unwrap()永远可用。
    • 我已将 iCheck 更改为选中,现在按预期工作。感谢您的帮助!
    • 淘汰赛 v3.4.2
    • @RalucaMicu 是的,“如何为 xyz 创建敲除绑定处理程序?” 确实是一个单独的问题。我试图弄清楚 iCheck 是如何工作的,但我以前从未使用过它,所以在看了几分钟后我很难说出可能是什么问题。
    猜你喜欢
    • 2020-05-03
    • 2017-01-10
    • 2017-02-22
    • 2014-12-01
    • 2014-11-29
    • 2016-01-22
    • 2015-03-23
    • 1970-01-01
    相关资源
    最近更新 更多