knockout.js - 使用 pjax 时在 history.back() 上消失的 knockout.js 绑定(bind)

标签 knockout.js pushstate pjax

我这里有一个测试用例:http://tremby.net/knockouttest/page1.php

我正在使用 pjax 进行页面转换。在上面的测试用例的第 1 页和第 2 页之间单击会异步加载两个页面,然后替换 #main 的内容元素。在此过程中会推送浏览器历史状态,因此位置栏中的 URL 会更新,并且后退按钮应该让我们回到原来的位置。

第 1 页的列表填充了 knockout 的 foreach绑定(bind)和List我定义的模型(在头部的内联脚本中)。在 ready在第 1 页,内联脚本运行 ko.applyBindings这样列表就被填充了。

“添加项目”按钮将项目添加到 View 模型,然后将其 knockout 添加到列表中。

添加一些项目,然后转到第 2 页,然后返回第 1 页,列表是新的,最初有 3 个项目,添加项目按钮仍然有效。这对我们的用例来说很好。

添加一些项目,然后转到第 2 页,但另一方面,使用浏览器的后退按钮返回第 1 页,这就是我的问题所在。新项目仍然可见(这很好,并且
当使用浏览器的后退按钮时,这对我们的用例至关重要),但“添加项目”按钮现在已损坏。将新项目推送到 observableArray 的代码肯定正在运行,但似乎绑定(bind)已经消失,因此 knockout 不知道添加新的 DOM 元素。

我无法运行 ko.applyBindingspopstate 上再次运行,或者 knockout 现在会认为我希望为列表中的每个项目复制每个现有项目,然后每次单击“添加项目”都会给出多个新项目。

我有一种强烈的感觉,我缺少一些明显的东西,但我找不到任何看起来对文档有帮助的东西。任何帮助将非常感激。

最佳答案

您看到这种行为是因为尽管已将 View 模型绑定(bind)到 UI,但您并没有将其持久化到浏览器历史可以访问它的任何地方,以便在您期望的状态下重建页面。使用浏览器的内置 back 也可以观察到这种行为。和 forward纽扣。我在解决这个问题时选择采用的通常模式如下;

首先,分配this到一个变量中,这将为您节省 hassle later on . View 模型现在应该看起来像这样;

function List(items) {
    var self = this;
    self.items = ko.observableArray(items)
    self.addItem = function(text) {
        self.items.push(text)
    }
}

现在创建一个计算的 observable 序列化你的 View 模型的当前状态。这完全取决于您选择如何实现它。
self.toJson = ko.computed(function(){
    /*** Serialise self.items() and return the string ***/
    return myJsonString;
});

接下来,将计算结果绑定(bind)到隐藏的输入,这将确保 View 模型在表单数据中持久化,从而允许您稍后重新水化 View 模型。
<input id="serialisedItems" type="hidden" data-bind="value: toJson" value="[1,4,3]" />

最后,在 $.ready() 上重新水化 View 模型以这种方式;
$(function() {
    var items = $('#serialisedItems').val();
    /*** Deserialise items before passing into the List ***/
    var list = new List(deserialisedItems);
    ko.applyBindings(list);
});

在这一点上我还应该指出,列表已经通过设置 <input> 的 value 属性进行了初始化。 .

关于knockout.js - 使用 pjax 时在 history.back() 上消失的 knockout.js 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17497946/

相关文章:

state - Pjax 保存自定义状态数据

javascript - 如何获取每个选定行的下拉列表值?

javascript - 我应该如何清理 KnockoutJS ViewModels?

javascript - 单页网站搜索引擎优化

javascript - 如何在 Ajax 响应中访问模型数据

javascript - Pjax 并在特定页面上重新加载 JavaScript

knockout.js - 在取消按钮上撤消更改

knockout.js - 从 subview 中的复选框更改访问父 View 模型

带有部分页面加载的 HTML5 History API 后退按钮

javascript - Yii2 Pjax 和 ActiveForm beforeSubmit 在重新加载后不起作用?