gpt4 book ai didi

jquery-mobile - 绑定(bind)停止更新

转载 作者:行者123 更新时间:2023-12-02 05:04:03 25 4
gpt4 key购买 nike

我一直在尝试创建一个自定义绑定(bind)来更新 float 图表,它在首次加载时似乎可以正常工作,但当我四处导航时它会退出。

这是场景,我在一个页面上有一个 ListView (这是在 jQuery Mobile 中),带有图表的小缩略图,图表旁边是一个 slider ,它绑定(bind)到导致要重新计算的图形点。当您单击其中一个列表项时,它会移动到显示更大版本图表的另一个页面,并允许您通过在文本框中键入来更改值(稍后,您将能够直接单击图表) .绑定(bind)看起来像这样:

    ko.bindingHandlers["plot"] = {
init: function (element, valueAccessor, allBindingsAccessor) {
var qe = $(element);
var page = qe.closest("div[data-role='page']");
page.bind("pageshow", function () {
ko.bindingHandlers["plot"].update(element, valueAccessor);
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var qe = $(element);
var page = qe.closest("div[data-role='page']");
var curr = $.mobile.activePage;
var val = ko.utils.unwrapObservable(valueAccessor());
var data = val.plotData();
if(data && page.prop("id") == curr.prop("id")) {
var marker = val.markerData();
var opt = val.chartOptions();
opt.yaxis.show = opt.xaxis.show = !qe.hasClass("graphThumb");
marker.points.radius = opt.yaxis.show ? 5 : 3.5;
$.plot(qe, [
data,
marker
], opt);
}
}
};

init 处理程序将其设置为在页面显示上绘制图形,因为当绘制到不可见的 div 时,flot 无法正常工作。更新将检查当前显示的页面是否与绑定(bind)的页面相同,并根据需要重新绘制图形。

对于 ListView 中的图表,它们会立即通过update 方法绘制并正常工作。但是,对于最初隐藏的页面,绘制图形的函数会触发,图形会绘制,但更新将不再起作用。然后,更糟糕的是,当您返回初始页面时,绑定(bind)到 pageshow 事件的函数会触发,重新绘制图形,但现在它们也停止更新。

View 模型看起来像这样:

var viewModel = (function () {
this.current = ko.observable(0);
this.plotData = ko.computed(function () {
var points = [];
// a bunch of calculations that depend on the value of current of this and other viewModels in a collection
return points;
}
}

我可以在计算的 plotData 中放置一个断点,然后看到它正在正确更新。只是这些更新不会触发绑定(bind)处理程序。

HTML 绑定(bind)看起来像这样:

<!-- the first, visible page -->
<div data-role="page" id="index">
<ul data-role="listview" data-bind="foreach: factors">
<li data-bind="attr: {id: listId}">
<a data-bind="attr: {href: idLink}">
<div class="graphThumb" data-bind="plot: $data"></div>
</a>
</li>
</ul>
</div>
<!-- hidden details pages -->
<!-- ko foreach: factors -->
<div data-role="page" data-bind="attr: { id: id }">
<div class="graphPlaceHolder" data-bind="plot: $data"></div>
</div>
<!-- /ko -->

更新:我稍微更改了我的绑定(bind),因为我意识到我可以在 pageshow 事件处理程序上调用 更新,这简化了事情,但不能解决问题。似乎这样做不会使 knockout 更新它对绑定(bind)的依赖性。

更新:另一个更新,将 val.plotData() 分配给变量无效,将其包含在我的 if 中也无效陈述。但是,我有另一个计算的可观察值,它取决于 current 值和父 View 模型的另一个属性,我可以检索并添加到我的 if 语句中!但是,我的解决方案可能是特定于普遍有用的。简而言之,knockout 将在每次更新时重新评估绑定(bind)的依赖关系,因此您需要确保无论任何条件逻辑如何,它都在评估重要的内容,否则它将停止更新。

最佳答案

所以我可以结束并将这个问题标记为已回答,我将简要总结一下我的经验。

自定义绑定(bind)的实现方式与 Knockout 中的计算属性相同(根据 KO 文档),并且计算属性所做的一件事是在每次执行时重新评估它们所依赖的属性。这意味着,如果您在计算属性(或自定义绑定(bind))中有一个条件,则只有在实际执行的条件分支中访问的属性才会被 knockout 监视更改。因此,例如,如果您拥有这样的属性:

var myComputedProperty = ko.computed(function() {
if(this.myBool()) {
$("#someElement").text(this.foo());
}
else {
$("#someElement").text(this.bar());
}
});

KO 将跟踪 myBool 的值并在其更改时重新计算该属性,但是,如果 myBool 为真,它还将跟踪 foo,如果 myBool 为假,它也会跟踪 bar,但它不会同时跟踪两者 - 因为它不需要。大多数情况下,这工作得很好。

在我的例子中,它失败了,因为我有一个不属于 View 模型的条件(因此不可观察),我需要它来跟踪 View 模型属性,无论条件是否被评估真或假。所以我有一些看起来像这样的东西:

if(page.prop("id") == curr.prop("id")) {
$("#someElement").text(this.foo());
}

这里比较的是绑定(bind)所在页面的 id 和 jQuery Mobile 提供的 $.mobile.activePage(而且,显然不可观察) .如果那些 id 匹配,则 knockout 将在 foo 更改时更新绑定(bind)。然而,如果他们不这样做,那么 knockout 将失去对 foo 的依赖,即使 id 在稍后的某个时间匹配,它也会失去依赖并赢得胜利当 foo 改变时不重新评估。

解决此问题的方法是确保无论条件如何都评估需要跟踪的任何属性。所以,这样的事情应该可以解决一般情况:

if(this.foo() && page.prop("id") == curr.prop("id")) {
$("#someElement").text(this.foo());
}

至于我为什么需要这个条件是因为 flot 在尝试将图形绘制到不可见的 div 时会变得非常困惑,所以当它不是当前页面时我需要跳过绘制图形。

关于jquery-mobile - 绑定(bind)停止更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13711528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com