Knockout.js 如何在使用多个可观测函数时激发不同的ko.computed函数
我正在尝试为一组数字制作热图绑定。 到目前为止,应该是相关地图一部分的数字应该由上下文指定 它在一定程度上起作用。。我仍然需要解决一点rgb算法,但在setHeat computed函数中存在问题的部分是其中的for循环 我想要的是,无论何时更改“max”或“min”,我都希望“elements”数组中当前的所有元素都更新其颜色 但是,当一个元素被添加到“elements”数组中时,我只想设置该元素的颜色,但这需要max和min,因此我不知道如何正确区分调用,以便min和max updates调用一个,而element update调用另一个 此外,我对如何改进我的绑定持开放态度Knockout.js 如何在使用多个可观测函数时激发不同的ko.computed函数,knockout.js,Knockout.js,我正在尝试为一组数字制作热图绑定。 到目前为止,应该是相关地图一部分的数字应该由上下文指定 它在一定程度上起作用。。我仍然需要解决一点rgb算法,但在setHeat computed函数中存在问题的部分是其中的for循环 我想要的是,无论何时更改“max”或“min”,我都希望“elements”数组中当前的所有元素都更新其颜色 但是,当一个元素被添加到“elements”数组中时,我只想设置该元素的颜色,但这需要max和min,因此我不知道如何正确区分调用,以便min和max updates调
<!-- ko foreach:items -->
<tr>
<td class="postCell">
<div class="ui-post-icon" data-bind="class: $parents[2].setPostIcon(post)"></div>
<span data-bind="text:post"></span>
</td>
<!-- ko foreach:combinations -->
<td data-bind="heat:{value:amount,context:'exotics'}"></td>
<!-- /ko -->
</tr>
<!-- /ko -->
ko.bindingHandlers.heat = {
init: function (element, value, allBindings, viewModel, bindingConext) {
var item = value();
var model = bindingConext.$root;
if (!model["koHeat"])
model["koHeat"] = {};
if (!model["koHeat"][item.context])
model["koHeat"][item.context] = ko.observable(new HeatContext());
var ctx = model["koHeat"][item.context];
if (!isNaN(item.value)) {
if (+item.value > ctx().max()) ctx().max(+item.value);
if (+item.value < ctx().min()) ctx().min(+item.value);
ctx().elements.push(element);
}
$(element).html(item.value).data('koHeat', item.value);
//set value
function HeatContext() {
var self = this;
this.max = ko.observable(0);
this.min = ko.observable(Number.MAX_VALUE);
this.elements = ko.observableArray([]);
this.setHeat = ko.computed(function () {
var max = self.max(),
min = self.min(),
elems = self.elements(),
mid = (max + min) / 2,
range = max - min,
r, g, b, x;
for (var i = 0; i < elems.length; i++) {
var val = $(elems[i]).data('koHeat');
x = (val - mid) / range;
if (x > 0) {
g = Math.abs(Math.round(x* 100));
b = 0.0;
r = Math.abs(Math.round((1.0 - x) * 100));
} else {
g = Math.abs(Math.round(x * 100));
b = Math.abs(Math.round((1.0 - x) * 100));
r = 0.0;
}
log(r,g,b);
$(elems[i]).css('color', "rgb(" + r + "," + g + "," + b + ")");
}
});
}
}
};
ko.bindingHandlers.heat={
init:function(元素、值、所有绑定、viewModel、bindingConext){
var item=value();
var model=bindingConext.$root;
如果(!model[“koHeat”])
模型[“koHeat”]={};
如果(!model[“koHeat”][item.context])
模型[“koHeat”][item.context]=ko.observable(newheatcontext());
var ctx=model[“koHeat”][item.context];
如果(!isNaN(项目值)){
如果(+item.value>ctx().max())ctx().max(+item.value);
如果(+item.value0){
g=数学绝对值(数学四舍五入(x*100));
b=0.0;
r=数学绝对值(数学四舍五入((1.0-x)*100));
}否则{
g=数学绝对值(数学四舍五入(x*100));
b=数学绝对值(数学四舍五入((1.0-x)*100));
r=0.0;
}
对数(r,g,b);
$(elems[i]).css('color','rgb(“+r+”,“+g+”,“+b+”));
}
});
}
}
};
编辑
我为这种情况迅速编了一把小提琴
不要将
setHeat
acomputed
,只需将其声明为HeatContext
中的私有函数,方法是删除this.
前缀并订阅min
和max
更改如下:
this.min.subscribe(setHeat);
this.max.subscribe(setHeat);
现在,setHeat
仅在更新min
或max
时运行,而不是在将元素推送到数组时运行
有许多方法可以改进此绑定。我会试着在几天内完成一个改进的版本。我将对此答案进行编辑。在注意到您的帖子之前,我找到了解决问题的方法,这里有一个小问题::我还没有研究过ko的订阅功能,所以感谢您的输入,但我仍然希望看到其他人如何进行这种绑定!我一直在尝试使用类似的方法来修改您的小提琴,因为您正在设置元素的html并添加jQuery
.data
,这基本上是以一种更静态的方式完成KOs的工作。我只是有点麻烦,因为我不知道你到底想做什么。如果你能解释整个事情,我会尝试应用更好的实践。