我有一个使用 KnockoutJS 3.4.2 构建的购物车页面。我在最新的 Chrome 中对此进行了测试。购物车中的产品正在通过 Ajax 加载。
然后将购物车填充到 HTML 表格中。
出于某种原因,当我在 TD 中绑定(bind)“productTitle”时,它可以工作,但当我尝试将它绑定(bind)在跨度中时,它不会。我还尝试使用模板:<span><!--ko text: productTitle--><!--/ko--></span>
但这也行不通。
这与页面加载时 observableArray 仍可能为空有关吗?我发现当我将“productTitle”放入 TD 文本中时,文本绑定(bind)就会起作用。
此外,由于某种原因,可观察计数不会绑定(bind)到数据绑定(bind)值的输入。也许我的 viewModel 的构建方式是错误的?
这是我的代码:
HTML
<tbody data-bind="foreach: productsInCart">
<tr data-bind="attr: {productOptionId: productOptionId}">
<td></td>
<td class="cart-title" data-bind="text: productTitle"></td>
<td data-bind="text: price"></td>
<td>
@*<span><!--ko text: productTitle--><!--/ko--></span>*@
<div click-action="" class="qtyminus"></div>
<input type='text' name="quantity" data-bind="value: count" class="qty"/>
<div click-action="" class="qtyplus"></div>
</td>
<td class="cart-total" data-bind="text: total"></td>@*
<td><a href="@Url.Action("RemoveProductOption", "ShoppingCart", new {id = product.ProductOptionId})" class="cart-remove"></a></td>*@
</tr>
</tbody>
JS
$(function () {
var productInCart = function(data) {
var self = this;
self.productOptionId = ko.observable(data.ProductOptionId);
self.price = ko.observable(data.Price);
self.count = ko.observable(data.Count);
self.productBrandName = ko.observable(data.ProductBrandName);
self.productOptionName = ko.observable(data.ProductOptionName);
self.productName = ko.observable(data.ProductName);
self.productFriendlyUrl = ko.observable(data.ProductFriendlyUrl);
self.productTitle = ko.computed(function () {
return self.productName() + " " + self.productOptionName();
});
self.total = ko.computed(function () {
return self.count() * self.price();
}, self);
return self;
}
function viewModel() {
var self = this;
self.productsInCart = ko.observableArray([]);
$.ajax({
type: "GET",
url: window.cartUrl,
dataType: "json",
contentType: 'application/json; charset=utf-8',
traditional: true, //// traditional option to true
success: function (result) {
console.log(result);
ko.utils.arrayForEach(result, function (data) {
self.productsInCart.push(new productInCart(data));
});
console.log(self.productsInCart());
}
});
}
var vm = new viewModel();
ko.applyBindings(vm);
});
AJAX 正在加载的对象:
[
{
ShoppingSessionId: 2061,
ProductOptionId: 3,
Price: 26.95,
Count: 1,
ProductBrandName: "G-Star",
ProductOptionName: "Maat 36/36",
ProductName: "G-Star Loose, 340166",
ProductFriendlyUrl: "g-star-3301-loose-dus",
TaxId: 1,
TaxRate: 21,
FirstProductImageId: 7,
Id: 48
}
]
无法绑定(bind)错误之一:
Uncaught ReferenceError: Unable to process binding "value: function (){return count }"
Message: count is not defined
at value (eval at parseBindingsString (knockout-3.4.2.js:280), <anonymous>:3:58)
at m (knockout-3.4.2.js:470)
at Function.Uc (knockout-3.4.2.js:204)
at Function.Vc (knockout-3.4.2.js:201)
at Function.U (knockout-3.4.2.js:200)
at Object.a.m.a.B (knockout-3.4.2.js:193)
at init (knockout-3.4.2.js:472)
at knockout-3.4.2.js:309
at Object.w (knockout-3.4.2.js:149)
at knockout-3.4.2.js:308
最佳答案
NOTE: To this arriving here, the issue was caused by a third-party library (StackTable) which was augmenting the KO bindings.
看起来你的代码是 Razor ?我注意到<span></span>
被注释掉了。这是你提到的有问题的跨度吗?
如果是这样,我建议将绑定(bind)放在 <span>
上元素本身。我不确定文本绑定(bind)是否支持虚拟标签的使用。
替换:
<span><!--ko text: productTitle--><!--/ko--></span>
与:
<span data-bind="text: productTitle"></span>
此外,作为“最佳实践”的一种手段,我不会将单个元素插入数组中。每次推送都会导致 knockout 重新评估依赖关系,并且将/可能导致重绘(即对性能不太好)。相反:
- 构建本地普通旧式 JavaScript 数组。
- 将元素插入其中。
- 将可观察数组的值设置为您刚刚构建的本地数组的值。
我还会包装 foreach
在逻辑检查中确定数组不为 null/未定义或为空。为了防止任何潜在的绑定(bind)错误。
关于javascript - 如何让我的 Knockout 代码正确绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44214438/