【问题标题】:Unable to process binding "event: function(){return {change:flagSalesOrderItemAsEdited} }"无法处理绑定“事件:函数(){return {change:flagSalesOrderItemAsEdited}}”
【发布时间】:2016-03-02 10:42:26
【问题描述】:

我目前正在做一个关于 Knockout 和 MVC(称为父子数据与 EF、MVC、Knockout、Ajax 和 Validation)的 Pluralsight 课程,我对此印象非常深刻,但突然间我得到了这个到目前为止的错误对我来说是个表演者。 这不仅是我的代码中的一个问题,而且也是我从 Pluralsight 下载的代码中的一个错误,我在他们的视频中看到了! 所以在编辑部分视图中我有:

<h2>@ViewBag.Title</h2>

<p data-bind="text: MessageToClient"></p>

<div>
    <div class="form-group">
        <label class="control-label" for="CustomerName">Customer Name:</label>
        <input class="form-control" name="CustomerName" id="CustomerName"
               data-bind="value: CustomerName, event: {change: flagSalesOrderAsEdited}"/>
    </div>
    <div class="form-group">
        <label class="control-label" for="PONumber">P.O. Number:</label>
        <input class="form-control" name="PONumber" id="PONumber"
               data-bind="value: PONumber, event: {change: flagSalesOrderAsEdited}"/>
    </div>
</div>
<table class="table table-stripe">
    <tr>
        <th>Product Code</th>
        <th>Quantity</th>
        <th>Unit Price</th>
        <th><button data-bind="click: addSalesOrderItem" class="btn btn-info btn-xs">Add</button></th>
    </tr>
    <tbody data-bind="foreach: SalesOrderItems">
        <tr>
            <td class="form-group">
                <input class="form-control input-sm"
                    data-bind="value: ProductCode, event: {change: flagSalesOrderItemAsEdited}, hasfocus: true" />
            </td>
            <td class="form-group">
                <input class="form-control input-sm"
                       data-bind="value: Quantity, event: {change: flagSalesOrderItemAsEdited}" />
            </td>
            <td class="form-group">
                <input class="form-control input-sm"
                       data-bind="value: UnitPrice, event: {change: flagSalesOrderItemAsEdited}" />
            </td>
            <td class="form-group">Delete</td>
        </tr>
    </tbody>
</table>
<p><button data-bind="click: save" class="btn btn-primary">Save</button></p>
<p>
    <a href="/" class="btn btn-default btn-sm">&laquo; Back to List</a>
</p>

我应用绑定;

<script type="text/javascript">
    var salesOrderViewModel = new SalesOrderViewModel(@Html.Raw(data));
    ko.applyBindings(salesOrderViewModel);
</script>

在我的 javascript 文件中

var ObjectState = {
    Unchanged: 0,
    Added: 1,
    Modified: 2,
    Deleted: 3
};

var salesOrderItemMapping = {
    'SalesOrderItems': {
        key: function(salesOrderItem) {
            return ko.utils.unwrapObservable(salesOrderItem.salesOrderItemId);
        },
        create: function(options) {
            return new SalesOrderViewModel(options.data);
        }
    }
};

SalesOrderItemViewModel = function(data) {
    var self = this;
    ko.mapping.fromJS(data, salesOrderItemMapping, self);

    self.flagSalesOrderItemAsEdited = function() {
        if (self.ObjectState() !== ObjectState.Added) {
            self.ObjectState(ObjectState.Modified);
        }

        return true;
    };
}

SalesOrderViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, salesOrderItemMapping, self);

    self.save = function() {
        $.ajax({
            url: "/Sales/Save",
            type: "POST",
            data: ko.toJSON(self),
            contentType: "application/json",
            success: function (data) {
                if (data.salesOrderViewModel !== null) {
                    ko.mapping.fromJS(data.salesOrderViewModel, {}, self);
                }

                if (data.newLocation !== undefined && data.newLocation !== null) {
                    window.location.href = data.newLocation;
                }
            }

        });
    }

    self.flagSalesOrderAsEdited = function () {
        if (self.ObjectState() !== ObjectState.Added) {
            self.ObjectState(ObjectState.Modified);
        }

        return true;
    }

映射是从服务器端视图模型派生的:

namespace SolutionName.Web.ViewModels
{
    public class SalesOrderViewModel : IObjectWithState
    {
        public SalesOrderViewModel()
        {
            this.SalesOrderItems = new ListStack<SalesOrderItemViewModel>();
        }

        public int SalesOrderId { get; set; }
        public string CustomerName { get; set; }
        public string PONumber { get; set; }
        public string MessageToClient { get; set; }
        public ObjectState ObjectState { get; set; }
        public List<SalesOrderItemViewModel> SalesOrderItems { get; set; } 
    }
}

namespace SolutionName.Web.ViewModels
{
    public class SalesOrderItemViewModel : IObjectWithState
    {
        public int SalesOrderItemId { get; set; }
        public string ProductCode { get; set; }
        public int Quantity { get; set; }
        public decimal UnitPrice { get; set; }
        public int SalesOrderId { get; set; }
        public ObjectState ObjectState { get; set; }
    }
}

错误发生在我对标志字段进行数据绑定的表中:

<td class="form-group">
                <input class="form-control input-sm"
                    data-bind="value: ProductCode, event: {change: flagSalesOrderItemAsEdited}, hasfocus: true" />
            </td>

我得到“flagSalesOrderItemAsEdited”未定义 它在淘汰赛脚本中失败了。

Unable to process binding "foreach: function(){return SalesOrderItems }"
Message: Unable to process binding "event: function(){return {change:flagSalesOrderItemAsEdited} }"
Message: 'flagSalesOrderItemAsEdited' is undefined

ex.message = "Unable to process binding \"" + bindingKey + ": " + bindings[bindingKey] + "\"\nMessage: " + ex.message;

第 3326 行异常

那么我该如何解决这个问题?

编辑 一种建议的解决方案是在 HTML 中使用 $parent 作为前缀。 所以我尝试了:

    <td class="form-group">
        <input class="form-control input-sm"
               data-bind="value: ProductCode, event: {change: $parent.flagSalesOrderItemAsEdited}, hasfocus: true" />
    </td>
    <td class="form-group">
        <input class="form-control input-sm"
               data-bind="value: Quantity, event: {change: $parent.flagSalesOrderItemAsEdited}" />
    </td>
    <td class="form-group">
        <input class="form-control input-sm"
               data-bind="value: UnitPrice, event: {change: $parent.flagSalesOrderItemAsEdited}" />
    </td>

这停止了抛出的异常。不过方法:

self.flagSalesOrderAsEdited = function () {
    if (self.ObjectState() !== ObjectState.Added) {
        self.ObjectState(ObjectState.Modified);
    }

未被调用。就好像它所在的类没有实例化一样。

【问题讨论】:

  • SalesOrderItems array 定义在哪里?
  • 我已经编辑了我的问题来回答你的问题@shu。 SalesOrderItems 数组从服务器端类映射到客户端类(我认为这是课程的聪明部分之一)

标签: asp.net-mvc knockout.js


【解决方案1】:

尝试以下操作。在循环内调用函数时使用$root

<td class="form-group">
            <input class="form-control input-sm"
                data-bind="value: ProductCode, event: {change: $root.flagSalesOrderItemAsEdited}, hasfocus: true" />
</td>

我们也可以使用$parent,它直接在当前上下文之外。 更多信息binding context

【讨论】:

  • 我不得不取消勾选这个答案。该解决方案确实阻止了抛出异常。但我遇到的问题是 SalesOrderItemViewModel 类似乎没有被实例化。目的是用户看到销售订单项目列表并修改其中一个。然后调用 self.flagSalesOrderAsEdited 函数,以便在服务器端数据库更新值。然而这个函数没有被调用,这意味着这个类还没有被实例化。
  • 我想知道这是否是ie11的问题。不幸的是,公司政策不允许我使用其他浏览器进行测试。
  • @arame3333,没问题,我没注意到代码里有,很高兴你找到了解决方案。
  • 我没有找到解决方案。我仍然卡住了。使用 $root 或 $parent 会阻止抛出异常,但不会调用 SalesOrderItemViewModel 类中的函数。
  • @arame3333 你能用更改更新问题吗,我猜可能是什么问题,你为什么不在SalesOrderViewModel 中移动flagSalesOrderAsEdited 方法,它实际上绑定到@987654328 @
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 2017-07-18
  • 2019-05-27
  • 1970-01-01
  • 2012-11-09
  • 2015-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多