javascript - Knockout.js 选择数据绑定(bind)值不被读取但被写入

标签 javascript knockout.js

这是我的 HTML 代码:

<!-- ko foreach: warehouseOrders().StoreOrders -->
                    <tr>
                        <td>
                            <b data-bind="text: Product"></b>
                        </td>
                        <td>
                            <b data-bind="text: Store"></b>`enter code here`
                        </td>
                        <td>
                            <b data-bind="text: Quantity"></b>
                        </td>
                        <td>
                            <select data-bind=" value: OrderStatusId , options: $parent.orderStatuses(), optionsText: 'Status', optionsValue: 'Id'"></select>
                            <b data-bind="text: OrderStatusId"></b>
                        </td>
                    </tr>
                    <!--/ko-->

因此 StoreOrders 包含所有属性:Product、Store、Quantity、OrderStatusId。

具体问题:选择选项:$parent.orderStatuses()包含订单状态列表(Id,状态)。我为选择设置了文本和值属性。一切正常,当选择一个选项时,它被写入对象的 OrderStatusId 属性中,但最初,OrderStatusId 包含一个值,该值应该在选择中读取和设置。因此,当我打开时,选择应该是该值。

以下是模型:

主类:

public class WarehouseDTO
    {
        public System.Guid Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public List<StoreOrderDTO> StoreOrders { get; set; }
        public List<StoreWarehouseDTO> StoreWarehouses { get; set; }
        public List<WarehouseProductDTO> WarehouseProducts { get; set; }
    }

和 StoreOrderDTO

public class StoreOrderDTO
    {
        public System.Guid Id { get; set; }
        public string Product { get; set; }
        public string Store { get; set; }
        public string Warehouse { get; set; }
        public int Quantity { get; set; }
        public System.Guid OrderStatusId { get; set; }
    }

Javascript:

self.warehouseOrdersRequest = function (item) {
        ajaxHelper('/api/OrderStatus', 'GET').done(function (data) {
            self.orderStatuses(data);
        });
        self.warehouseOrders(item);
    }

这里的 item 代表 1 个 WarehouseDTO 类型的对象,和OrderStatuses给出一个对象数组 {Id,Status}

表格的完整代码

<!--ko if : warehouseOrders()-->
    <div>
        <div class="col-md-4">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h2 class="panel-title"><b data-bind="text: warehouseOrders().Name"></b> - Orders</h2>
                </div>
                <table class="table">
                    <tr>
                        <th>
                            @Html.DisplayName("Product")
                        </th>
                        <th>
                            @Html.DisplayName("Store")
                        </th>
                        <th>
                            @Html.DisplayName("Quantity")
                        </th>
                        <th>
                            @Html.DisplayName("Order Status")
                        </th>
                    </tr>

                    <!-- ko foreach: warehouseOrders().StoreOrders -->
                    <tr>
                        <td>
                            <b data-bind="text: Product"></b>
                        </td>
                        <td>
                            <b data-bind="text: Store"></b>
                        </td>
                        <td>
                            <b data-bind="text: Quantity"></b>
                        </td>
                        <td>
                            <select data-bind=" value: OrderStatusId , options: $parent.orderStatuses(), optionsText: 'Status', optionsValue: 'Id'"></select>
                            <b data-bind="text: OrderStatusId"></b>
                        </td>
                    </tr>
                    <!--/ko-->
                </table> 
            </div>
            <a href="#" data-bind="click: closeWarehouseOrders" class="btn btn-defaul">Cancel</a>
            <a href="#" data-bind="click: saveWarehouseOrders" class="btn btn-defaul">Save</a>
        </div>
    </div>
    <!--/ko-->

我注意到一些事情,在我选择一个项目后,它被写入 OrderStatusId <b data-bind="text: OrderStatusId"></b>显示(以前没有),是的,我确信其中有一个值。

最佳答案

因为orderStatuses是异步加载的,而当前状态不是,knockout 无法正确初始化 <select>数据绑定(bind)在这里:

<select data-bind=" value: OrderStatusId , options: $parent.orderStatuses(), optionsText: 'Status', optionsValue: 'Id'"></select>

绑定(bind)时,$parent.orderStatuses()是一个空数组。 OrderStatusId是一个字符串。没有选项可以查找 option.Id == value用于设置初始值。

更新可观察选项数组时, knockout 显然不会重试将当前选定的值与新选项之一进行匹配。 (需要引用,我试图查找来源来支持这一点,但找不到足够快的速度......)

解决此问题的一种方法是阻止 <select> 的初始化当 statuses尚未加载:

<!-- ko if: orderStatuses().length -->
<select data-bind="options: orderStatuses"></select>
<!-- /ko -->

您可以在下面的示例中看到此修复。当您删除虚拟if时绑定(bind)元素,您会看到初始状态不再设置。另外,当你交换 setItem 的顺序时和setStatuses ,您会发现不再需要额外的 if-bind。

var vm = {
  item: ko.observable(),
  statuses: ko.observableArray([])
}

ko.applyBindings(vm);

var setItem = function() {

  vm.item({
    orders: ko.observableArray([{
        text: "Item 1",
        status: ko.observable(0)
      }, {
        text: "Item 2",
        status: ko.observable(1)
      }

    ])
  });
}

var setStatuses = function() {
  vm.statuses([{
    label: "Status 0",
    id: 0
  }, {
    label: "Status 1",
    id: 1
  }]);
}

setItem();
setStatuses();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<!-- ko if: item -->
<ul data-bind="foreach: item().orders">
  <li>
    <div data-bind="text: text"></div>
    
    <!-- ko if: $parent.statuses().length -->
    <select data-bind="options: $parent.statuses, value: status, optionsText: 'label', optionsValue: 'id'"></select>
    <strong data-bind="text: 'status: ' + status()"></strong>
    <!-- /ko -->
  </li>
</ul>
<!-- /ko -->

关于javascript - Knockout.js 选择数据绑定(bind)值不被读取但被写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39139464/

相关文章:

javascript - 动态字段的可靠下拉菜单

javascript - video.js 结束事件

javascript - 正则表达式的行为因客户端而异

c# - 将 MVC 数据传递给 Knockout View 模型

c# - 在 Knockout foreach 数据绑定(bind)中使用服务器端对象类型

javascript - Durandal 撰写时的装订处理不正确

javascript - 设置 AngularJS 范围标签的值

javascript - 如何将选定的日期从日期选择器获取到后端的方法

javascript - 如何使用 RequireJS 只加载和运行一次模块

javascript - 将元素添加到数组中所有对象的智能方法? js/jquery/knockout