Javascript 自定义敲除绑定意外触发两次
我已经编写了一个自定义绑定处理程序,将viewmodel数据绑定到highcharts图表。这实际上有两个部分,一个绑定highcharts所需的初始配置,第二个绑定系列到图表 下面是bindingHandler代码 现在我为此设置了两个测试,第一个测试按预期工作。它将一个图表与多个系列绑定,当我添加到绑定到该系列的可观察数组时,它只会更新图表一次。单击add按钮时,查看并观看控制台。您将得到的输出是 更新容器对象{chart={…} 序列展开容器[Object{name=Scenario0,color=red,data=[9]},Object{name=Scenario1,color=green,data=[9]}] 这表明我们只看过上面的代码一次 现在检查我的副手:。这与highcharts的初始配置略有不同,因为highcharts的初始配置是一个计算的可观察配置,序列也是如此。单击此按钮上的“添加”按钮时,您将看到绑定执行了两次: 更新container2对象{chart={…},xAxis={…},series=[1]} 序列展开的容器2[对象{name=Scenario2,color=blue,data=[2]}] 更新container2对象{chart={…},xAxis={…} 序列展开的容器2[对象{name=Scenario2,color=blue,data=[2]}]Javascript 自定义敲除绑定意外触发两次,javascript,knockout.js,bindinghandlers,Javascript,Knockout.js,Bindinghandlers,我已经编写了一个自定义绑定处理程序,将viewmodel数据绑定到highcharts图表。这实际上有两个部分,一个绑定highcharts所需的初始配置,第二个绑定系列到图表 下面是bindingHandler代码 现在我为此设置了两个测试,第一个测试按预期工作。它将一个图表与多个系列绑定,当我添加到绑定到该系列的可观察数组时,它只会更新图表一次。单击add按钮时,查看并观看控制台。您将得到的输出是 更新容器对象{chart={…} 序列展开容器[Object{name=Scenario0,c
我猜在highcharts绑定处理程序中使用allBindings.get'series时,我设置了一个对它的依赖关系,当两个绑定都更改时,我会执行两次highcharts绑定。我的问题是,是否有任何方法可以停止此操作,或以任何其他方式编写此功能以避免发生这种情况?我不确定这是否会对您有所帮助,因为上面评论中的nemesv回答似乎非常接近您想要实现的目标,即停止双重更新 然而,我已经花了一点时间在它上面,所以我将向你展示我的想法,希望它能有所帮助 我不知道nemesv提到的peek方法有多棒,所以我研究了为什么它会根据计算结果更新两次 我看到你的self.breakdownhart正在访问可观察的currentScenario,当我将其作为测试删除时,第二次更新没有发生 这让我思考,为什么你需要在x轴设置中使用它 因此,我在场景中添加了一个新属性,以返回当前场景名称
self.name='Scenario' + self.number;
然后,对于基本场景,将其更改为基本场景,以确保仅该系列的标题正确显示
为了确保图例/轴是正确的,我向图表对象添加了一个名为baseSeriesName的新属性
self.breakdownChart = ko.computed(function(){
return {
baseSeriesTitle: baseScenario.name,
这被设置为baseScenario的名称
最后,为了在BindingHandler中将这一切联系在一起,我更新了其中的xAxis:
//set the xAxis titles, only add the second title if different from the base
valueUnwrapped.xAxis={
categories: [valueUnwrapped.baseSeriesTitle, valueUnwrapped.baseSeriesTitle!=seriesUnwrapped[0].name ? seriesUnwrapped[0].name:'']
}
这是一点重构,但它实现了您的目标;希望能有帮助
哦,我还向视图模型中添加了一个chartType observable,并在图表定义分解图computed中使用它来测试如果图表在不同的observable上刷新,并且它仍然正确初始化,则不会发生双重更新-因此小提琴显示图表类型更新,不需要双重更新。您会得到两次更新,因为淘汰更新会在其依赖项更改时立即计算可观察项,并且您的绑定有两个依赖项,每个依赖项依次更新 解决这个问题的一种方法是使用一种技术来延迟绑定的更新。一种简单的方法是使用,如下所示: 延迟更新使用setTimeout执行更新,这意味着更新是异步进行的。如果希望对特定更新进行同步,可以使用ko.tasks.processImmediate:
您必须决定何时调用更新函数。因此,当绑定属性更改或序列绑定属性更改时。然后使用peek而不是ko.unwrap:var seriesUnwrapped=series.peek;或var valueUnwrapped=value.peek;在调用peek之前,您当然需要检查值或序列是否真的可以观察到。@nemesv-这是一个非常好的开始,仅此一项就解决了双重调用问题。然而,在做了那个简单的更改之后,我的第一个小提琴将不再更新,因为它绑定到一个计算序列,而是一个静态highchart属性。你已经有了三分之二的答案。如果你用var valueUnwrapped=ko.isObservablevalue这个值来回答这个问题?value.peek:值;它解决了这两个问题。但是如果绑定为highchart:yourProp,series:otherProp,并且只有yourProp更改,而otherProp没有更改,那么它将无法正确更新图表。。。
//set the xAxis titles, only add the second title if different from the base
valueUnwrapped.xAxis={
categories: [valueUnwrapped.baseSeriesTitle, valueUnwrapped.baseSeriesTitle!=seriesUnwrapped[0].name ? seriesUnwrapped[0].name:'']
}
ko.tasks.processImmediate(function() {
self.scenarios.push(newScenario);
self.currentScenario(newScenario);
});