据我所知,使用带有Knockout的jQuery事件处理程序是不好的做法,但目前我想继续这条路径。我正在寻找有关如何使用jQuery中的click事件更新视图模型的说明,正如我在this Fiddle中所述。
预期的行为是:单击颜色按钮(即Red, Green, Blue
),然后单击UPDATE!
以显示相应颜色的数据。例如,单击红色 - >更新将在DOM中吐出“红花太阳”。然后点击蓝色 - >更新将产生“蓝天海洋”。
我认为问题在于我的observable和with: colors
数据绑定,但我不完全理解为什么。对于我来说,这基本上是针对Knockout的为期2天的速成课程,我觉得这应该比它更容易实现。
请告诉我光明!
<div data-bind="with: colors">
<h4 data-bind="text: name"></h4>
<div data-bind="foreach: things">
<span data-bind="text: $data" />
</div>
</div>
function Sample(data) {
var self = this;
self.colors = ko.observableArray();
self.currentColor = ko.observable();
ko.mapping.fromJS(data, {}, self);
}
var sample = new Sample({
"colors": [{
"name": "red",
"things": ["flower", "sun"]
}, {
"name": "green",
"things": ["tree", "money"]
}, {
"name": "blue",
"things": ["sky", "ocean"]
}]
});
ko.applyBindings(sample);
var clicked;
$("button").on("click", function() {
clicked = this.className;
});
$(".update").on("click", function() {
if (clicked === "red") {
// ???
}
if (clicked === "green") {
// ???
}
if (clicked === "blue") {
// ???
}
});
答案 0 :(得分:1)
我更新了你的小提琴,以匹配你想要的东西。 但我希望你真的会忽视这种方式。 请检查此fiddle。
我所做的是找到name
变量clicked
的颜色。
$(".update").on("click", function() {
var foundColor = sample.colors().find(function(color){
return color.name() === clicked;
});
sample.currentColor(foundColor);
});
你的with binding的值应该是currentColor,而不是你的可观察数组。
<div data-bind="with: currentColor">
但是,这不是正确的方法,你应该阅读click绑定,它会让你开始,并将有一个更清洁的实现,而且更短。
答案 1 :(得分:1)
如果要渲染所有颜色,则必须使用foreach
绑定。这有点像with
数组中每个项目的自动colors
绑定:
<div data-bind="foreach: colors"> ... </div>
我不认为你在使用淘汰赛时应该使用jQuery进行处理,所以我将解释如何使用click
绑定。
点击装订的基本布局是:
click: function(currentlyBoundData, event) { /* ... */ }
这意味着,当您使用foreach
绑定时,它会将点击的数据与点击事件一起发送。
让我们首先在您的viewmodel中添加一个点击处理程序:
self.clickHandler = function(clickedItem, event) {
console.log(clickedItem);
};
现在,将此处理程序方法附加到每种颜色的点击:
<div data-bind="foreach: colors">
<h4 data-bind="text: name, click: $parent.clickHandler"></h4>
</div>
注意$parent
:它链接到foreach
级别的数据绑定上下文,即Sample
视图模型。
现在你已经制作了一个可以被所有颜色重用的方法,你可以编写其余的逻辑代码:
click
绑定将点击的项目作为第一个参数传递我们可以直接将observable绑定到click
方法
data-bind="click: $parent.currentColor"
最后,您需要一个update
方法:
currentColor
self.currentColor()
selectedColor
:self.selectedColor(self.currentColor())
function Sample(data) {
var self = this;
self.colors = ko.observableArray();
self.currentColor = ko.observable();
self.selectedColor = ko.observable();
self.updateColor = function() {
self.selectedColor(self.currentColor());
};
ko.mapping.fromJS(data, {}, self);
}
var sample = new Sample({
"colors": [{
"name": "red",
"things": ["flower", "sun"]
}, {
"name": "green",
"things": ["tree", "money"]
}, {
"name": "blue",
"things": ["sky", "ocean"]
}]
});
ko.applyBindings(sample);
.selected {
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div data-bind="foreach: colors">
<h4 data-bind="text: name, click: $parent.currentColor, css: {'selected' : $parent.currentColor() === $data}"></h4>
</div>
<button data-bind="click: updateColor">load last clicked</button>
<div data-bind="with: selectedColor">
Selection: <strong data-bind="text: name"></strong>
</div>