未捕获的类型错误:无法通过淘汰处理绑定“if”

Posted

技术标签:

【中文标题】未捕获的类型错误:无法通过淘汰处理绑定“if”【英文标题】:Uncaught TypeError: Unable to process binding "if" with knockout 【发布时间】: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);

【问题讨论】:

【参考方案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 是如何工作的,但我以前从未使用过它,所以在看了几分钟后我很难说出可能是什么问题。

以上是关于未捕获的类型错误:无法通过淘汰处理绑定“if”的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的类型错误:无法读取未定义的属性“名称”

Solidity - “未捕获的类型错误:无法读取未定义的属性‘合同’”

未捕获的类型错误:无法读取 JQuery DataTable 未定义的属性“mData”

未捕获的类型错误:无法读取未定义的属性“获取”

无法读取未定义的属性“样式”——未捕获的类型错误

JQuery:未捕获的类型错误:无法读取未定义的属性“调用”