javascript - 当可观察更新时,选择的选项不会更新,尽管 optionsValue 确实
问题描述
在下面的代码中,产品(用 表示productVM
)有一个可观察的属性 ( productName
),其中包含两种语言(英语和法语)的名称。
添加acartItem
并选择产品后,我希望在单击“更改语言”按钮时更新其显示名称(例如,如果选择“门”,然后单击“更改语言”,则显示名称应该是法语版本(只是英语单词加上法语后缀“eux”))。
但这不起作用:选项确实发生了变化,但所选选项更改为标题选项。
需要更改/添加什么来修复它?
var handlerVM = function () {
var self = this;
self.cartItems = ko.observableArray([]);
self.availableProducts = ko.observableArray([]);
self.language = ko.observable();
self.init = function () {
self.initProducts();
self.language("english");
}
self.initProducts = function () {
self.availableProducts.push(
new productVM("Shelf", ['White', 'Brown']),
new productVM("Door", ['Green', 'Blue', 'Pink']),
new productVM("Window", ['Red', 'Orange'])
);
}
self.getProducts = function () {
return self.availableProducts;
}
self.getProductName = function (product) {
if (product != undefined) {
return self.language() == "english" ?
product.productName().english : product.productName().french;
}
}
self.getProductColours = function (selectedProductName) {
selectedProductName = selectedProductName();
// if not caption
if (selectedProductName) {
var matched = ko.utils.arrayFirst(self.availableProducts(), function (product) {
return (self.language() == "english" ? product.productName().english : product.productName().french) == selectedProductName;
});
return matched.availableColours;
}
}
self.addCartItem = function (a, b, c, d) {
self.cartItems.push(new cartItemVM());
}
self.changeLanguage = function () {
self.language() == "english" ?
self.language("french") :
self.language("english");
}
}
self.productVM = function (name, availableColours) {
var self = this;
self.productName = ko.observable({
english: name,
french: name + "eux",
});
self.availableColours = ko.observableArray(availableColours);
}
self.cartItemVM = function () {
var self = this;
self.cartItemName = ko.observable();
self.cartItemColour = ko.observable();
}
var handler = new handlerVM();
handler.init();
ko.applyBindings(handler);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<div data-bind="foreach: cartItems">
<div>
<select data-bind="options: $parent.getProducts(),
optionsText: function (item) { return $parent.getProductName(item); },
optionsValue: function (item) { return $parent.getProductName(item); },
optionsCaption: 'Choose a product',
value: cartItemName"
>
</select>
</div>
<div>
<select data-bind="options: $parent.getProductColours(cartItemName),
optionsText: $data,
optionsCaption: 'Choose a colour',
value: cartItemColour,
visible: cartItemName() != undefined"
>
</select>
</div>
</div>
<div>
<button data-bind="text: 'add cart item', click: addCartItem" />
<button data-bind="text: 'change language', click: changeLanguage" />
</div>
</div>
解决方案
当您更改options
您的选择时会出现您的问题。在更改期间,您value
绑定的 observablecartItemName
包含英文字符串。例如:Door
。一旦你改变了语言,没有一个单一option
的返回Door
它的optionsValue
表达,从而完全清除value
。
最好的解决方案是存储对实际视图模型的引用,而不仅仅是其字符串名称。这确实需要您移动其他一些零碎的东西,因为您要手动更新很多东西。
改变的起点:
// Remove
self.cartItemName = ko.observable();
// Add
self.cartItem = ko.observable();
// Change
<select data-bind="...
value: cartItem
" />
在一个工作片段中,进行了一些其他更改以使我的工作更轻松:
var handlerVM = function () {
var self = this;
self.cartItems = ko.observableArray([]);
self.language = ko.observable("english");
self.availableProducts = ko.observableArray([
new productVM("Shelf", ['White', 'Brown']),
new productVM("Door", ['Green', 'Blue', 'Pink']),
new productVM("Window", ['Red', 'Orange'])
]);
self.productNameFor = function(product) {
return product.productName()[self.language()];
};
self.addCartItem = function (a, b, c, d) {
self.cartItems.push(new cartItemVM());
}
self.changeLanguage = function () {
self.language() == "english" ?
self.language("french") :
self.language("english");
}
}
self.productVM = function (name, availableColours) {
var self = this;
self.productName = ko.observable({
english: name,
french: name + "eux",
});
self.availableColours = ko.observableArray(availableColours);
}
self.cartItemVM = function () {
var self = this;
self.cartItem = ko.observable();
self.cartItemColour = ko.observable();
}
ko.applyBindings(new handlerVM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<div data-bind="foreach: cartItems">
<div>
<select data-bind="options: $root.availableProducts,
optionsText: $root.productNameFor,
optionsCaption: 'Choose a product',
value: cartItem"
>
</select>
</div>
<div data-bind="with: cartItem">
<select data-bind="options: availableColours,
optionsCaption: 'Choose a colour',
value: $parent.cartItemColour"
>
</select>
</div>
</div>
<div>
<button data-bind="text: 'add cart item', click: addCartItem" />
<button data-bind="text: 'change language', click: changeLanguage" />
</div>
</div>
推荐阅读
- r - Hosting R Plumber on AWS EC2
- python - Jupyter notebook 未通过 anaconda promot 或 cmd 加载
- java - 使用电子邮件中的链接下载资源时在浏览器中获取 ERR_INVALID_RESPONSE
- python - 用于多进程的 Python
- javascript - 如何根据视口的宽度编写这个 var 来设置 headerHeight?
- ios - 如何使用 nix 为 iPhone 进行交叉编译?
- javascript - 如何获取最后两个 URL 段?
- reactjs - 在控制台中正确返回数据之前,我需要单击两次
- javascript - 给定一个表示非负整数的非空数字数组,将整数加一(javascript)
- angular - 如何通过Angular中的url更改动态更改类