我目前正在进行关于Knockout和MVC的Pluralsight课程(称为EF,MVC,Knockout,Ajax和Validation的父子数据),我对此印象非常深刻,但突然间我得到了迄今为止的这个bug对我来说是一个表演的限制。 这不仅是我的代码中的一个问题,它也是从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;
}
映射是从服务器端viewModels派生的:
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行例外
那么我该如何解决这个问题呢?
EDIT 一个建议的解决方案是使用$ parent作为HTML中的前缀。 所以我试过了:
<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);
}
未被调用。好像它所在的课程没有被实例化。
答案 0 :(得分: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