淘汰赛未捕获 RangeError:超过最大调用堆栈大小

Posted

技术标签:

【中文标题】淘汰赛未捕获 RangeError:超过最大调用堆栈大小【英文标题】:Knockout Uncaught RangeError: Maximum call stack size exceeded 【发布时间】:2018-07-28 00:10:32 【问题描述】:

我正在使用 Knockout Validation,当我将视图模型发布到控制器时,我收到异常“未捕获 RangeError:超出最大调用堆栈大小”。我有一个主视图模型,因为我在同一个视图中使用 CustomerViewModel(2 个引导模式),第一个是创建客户,另一个是编辑客户。知道为什么会抛出异常吗?

[HttpPost]
public JsonResult SaveCustomer(Customer model)

    string status = "ok";

    return Json(status, JsonRequestBehavior.AllowGet);


public class Customer

    public string Name  get; set; 

$(document).ready(function () 

    var CustomerSetupViewModel = function () 
        var self = this;

        self.Name = ko.observable("");

        self.Validation = ko.validatedObservable([
            self.Name.extend(
                required: true
            )    
        ]);

        var CustomerSetup = 
            Name: self.Name
        ;

        self.CustomerSetup = ko.observable();

        self.GetCustomer = function ()             
            var data =  Name: "ToBeUpdated" ;
            self.CustomerSetup(data);
        

        self.Save = function () 
            
            if (self.Validation.isValid()) 
                
                $.post("/Home/SaveCustomer", self, function (data) 
                    if (data == "ok")                    
                        alert("successful");                    
                    else
                        alert("error");
                );

            
            else 
                self.Validation.errors.showAllMessages();
            
        

        self.Update = function ()             
            var name = self.CustomerSetup().Name;            
            alert(name);
                
    

    var MainViewModel = function ()         
        self = this;
        self.NewCustomer = new CustomerSetupViewModel();
        self.EditCustomer = new CustomerSetupViewModel();
    

    vm = new MainViewModel();
    ko.applyBindings(vm);

    $("#updateCustomer").click(function ()         
        vm.EditCustomer.GetCustomer();
    );

    $("#NewCustomer").on("show.bs.modal", function (e) 
        vm.NewCustomer.Name("");        
        vm.NewCustomer.Validation.errors.showAllMessages(false);
    )

);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<hr />
<a id="addCustomer" class="btn btn-default" data-toggle="modal" data-target="#NewCustomer">Add Customer</a>
<a id="updateCustomer" class="btn btn-default" data-toggle="modal" data-target="#UpdateCustomer">Update Customer</a>

<!-- Modal -->
<div id="NewCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="NewModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="NewModalLabel">New Customer</h4>
            </div>
            <div class="modal-body">
                <div class="panel panel-default">
                    <div class="panel-heading"></div>
                    <div class="panel-body">

                        <div class="row">
                            <div class="col-md-4">
                                <label>Customer Name</label>
                                <input type="text" id="Name" class="form-control" data-bind="value: NewCustomer.Name" />
                            </div>
                        </div>

                    </div>
                    <div class="modal-footer">
                        <a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
                        <a role="button" class="btn btn-primary" data-bind="click: NewCustomer.Save()">Save</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Modal -->
<div id="UpdateCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="UpdateModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="UpdateModalLabel">Update Customer</h4>
            </div>
            <div class="modal-body">
                <div class="panel panel-default">
                    <div class="panel-heading"></div>
                    <div class="panel-body" data-bind="foreach: EditCustomer.CustomerSetup">

                        <div class="row">
                            <div class="col-md-4">
                                <label>Customer Name</label>
                                <input type="text" id="Name" class="form-control" data-bind="value: Name" />
                            </div>
                        </div>

                    </div>
                    <div class="modal-footer">
                        <a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
                        <a role="button" class="btn btn-primary" data-bind="click: EditCustomer.Update">Update</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.js"></script>

【问题讨论】:

该错误与KO无关。它发生在服务器级别。请显示您的服务器模型对象和控制器代码。另外,另一方面,为什么你有一个名为GetCustomer 的方法但它不返回任何东西?我会重命名它。 GetCustomer 方法将用于进行 ajax 调用以获取每个客户的数据。所有的代码都是一个例子。问题不在服务器上,因为如果我删除 KO 验证代码,则帖子成功,无论如何这是服务器代码: [HttpPost] public JsonResult SaveCustomer(Customer model) string status = "ok";返回 Json(状态,JsonRequestBehavior.AllowGet); “这是服务器代码”是什么意思?服务器代码是您在 SaveCustomer 中拥有的内容,以及该方法接收的任何内容作为输入。 “服务器模型对象”是什么意思?无论如何,如果 KO 验证正常,Save 功能显然会向服务器发送帖子,这没有科学...... 好吧,你似乎知道你在做什么,所以我会放过你,因为我不懂“科学”... 【参考方案1】:

我在 Save 函数中使用 ko.toJSON() 后找到了解决方案。 ko.toJSON() 生成一个没有 Knockout 构造的 javascript 对象。这样我就避免了无限循环。

self.Save = function () 

        if (self.Validation.isValid()) 

            $.post("/Home/SaveCustomer", ko.toJSON(self), function (data) 
                if (data == "ok")                    
                    alert("successful");                    
                else
                    alert("error");
            );

        
        else 
            self.Validation.errors.showAllMessages();
        
    

【讨论】:

以上是关于淘汰赛未捕获 RangeError:超过最大调用堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的 RangeError:仅在生产中超出最大调用堆栈大小

“未捕获的 RangeError:在 Dt (jquery.min.js:2) 处超出了最大调用堆栈大小”

RangeError:超过最大调用堆栈大小 React Native

nodeJs巨大的数组处理抛出RangeError:超过最大调用堆栈大小

“(AppContainer)的RangeError:最大调用堆栈大小超过” - 阵营与反应热装载机

未捕获的 RangeError:Chrome 上的语言标签无效