【发布时间】: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">« 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 数组从服务器端类映射到客户端类(我认为这是课程的聪明部分之一)