这是我的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()
包含orderstatuses列表(Id,Status)。我为select设置了text和value属性。一切正常,当选择一个选项时,它被写入对象的OrderStatusId属性,但最初,OrderStatusId包含一个值,该值应在select中读取和设置。因此,当我打开时,select应该在该值上。
以下是模型:
主要课程:
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表示WarehouseDTO
类型的1个对象,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>
(它之前没有),是的,我确定它中有一个值。
答案 0 :(得分:1)
因为orderStatuses
被加载为异步,而当前状态不是,所以knockout无法在此处正确初始化<select>
数据绑定:
<select data-bind=" value: OrderStatusId , options: $parent.orderStatuses(), optionsText: 'Status', optionsValue: 'Id'"></select>
在绑定时,$parent.orderStatuses()
是一个空数组。 OrderStatusId
是一个字符串。没有选项可以查找用于设置初始值的option.Id == value
。
更新observable options数组时,knockout 显然不会重试将当前选定的值与其中一个新选项匹配。 (引用需要,我试图查找源代码来支持它,但是找不到它足够快......)
解决此问题的一种方法是在<select>
尚未加载时阻止初始化statuses
:
<!-- ko if: orderStatuses().length -->
<select data-bind="options: orderStatuses"></select>
<!-- /ko -->
您可以在下面的示例中看到此修复程序。删除虚拟if
绑定元素后,您将看到不再设置初始状态。此外,当您更换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 -->