我正在使用HC的1.10.3版本,而我正在尝试为查找视图扩展ViewModel。我想为产品添加一个新的布尔属性,以便我可以检查它并根据需要在视图中添加一些html。因此,在Category.js中,我认为我循环遍历数据,并将新属性添加到ViewModel,以便可以在View中使用它。循环是我遇到问题的地方。当我调试代码时,循环按预期添加属性,但是当页面完成加载并检查源时,Json对象中没有任何修改。
function HcDrillDownFilterViewModel(data, $form, catId, modId) {
var DECIMAL_SEP = ".";
var self = this;
for (var i = 0; i < data.Products.length; i++) {
var p = data.Products[i];
if (p.ProductName.toLowerCase().indexOf('nike') > -1) {
p.NikeBrand = true;
} else {
p.NikeBrand = false;
}
}
// Binding
self.model = ko.observable();
self.minPrice = ko.observable(data.SelectedMinPrice);
self.maxPrice = ko.observable(data.SelectedMaxPrice);
有什么想法让我将这些更改留给ViewModel?
答案 0 :(得分:1)
您遇到的只是一个关于KnockoutJS如何工作的微小学习曲线。由于它是一个包含大量绑定和其他工作的框架,因此您需要使用它。通常情况下,这意味着原始JS代码段可能无法正常工作。
说实话,我自己很少接触这个观点,因为我对KO也不是很精通,但我设法根据你的问题得到一个概念验证。
首先,在您的代码中,您正在更新数组对象,但您只是在绑定到视图的其中一个位置更新它。它需要在两个地方完成。这是您没有看到更新应用的主要原因。
我将这个调用放在我在同一个JS文件中创建的方法中,代替原始代码段。
// update Products how you'd like
data.Products = parseProducts(data.Products);
然后,我在handleDrillDown()
函数的顶部做了同样的事。
// this needs to get called here too
data.Products = parseProducts(data.Products);
现在,可能有更好的方法来执行此操作,但此文件中的最终更新通过添加您在下面看到的功能完成了所有工作。就我而言,我使用的是开箱即用的样品,只需检查Brown Fedora。您还会注意到我正在使用Knockout提供的内置foreach。每当使用框架时都应该这样做。
function parseProducts(products) {
// instantiate a local array of products to work with
var arrProducts = products;
// loop through and apply your changes
ko.utils.arrayForEach(arrProducts, function (p) {
// check your condition
if (p.ProductName.toLowerCase().indexOf("fedora") > -1) {
p.CoolHat = true; // new property that wasn't there before
} else {
p.CoolHat = false; // new property that wasn't there before
}
});
// send back the new array
return arrProducts;
}
最后,我通过在产品名称后添加此代码段来更新钻取Razor视图标记,以查看我的更改是否按照我的预期反映出来。
<span data-bind="if: CoolHat" style="font-weight:bold; color: red;">This is a really cool hat!</span>
结果是只有Fedora被这个文本“标记”了。