在历史回归之后,淘汰赛绑定会被解除绑定

Cou*_*ren 9 javascript jquery html5 ruby-on-rails knockout.js

我正在使用knockout和rails 4构建一个Web应用程序.我有一个家庭控制器来提供主要的htmls和javascripts.在application.js.erb里面我声明了我的viewModel:

var appViewModel = function appViewModel(){
    var self = this;
    self.navLinks = ['whoarewe','business'];
}

$(document).ready(function() {
    ko.applyBindings(new appViewModel());
});
Run Code Online (Sandbox Code Playgroud)

home/index.html.erb看起来像这样:

<div class="app_navbar">
    <ul class="navLinks">
        <!--ko foreach:navLinks-->
        <li><a data-bind="text: $data"></a></li>
        <!--/ko-->
    </ul>
</div>

<%= video_tag "Student_Resume1.mp4", :size => "320x240", :controls => true, :autobuffer => true %>
Run Code Online (Sandbox Code Playgroud)

当我通过正常的浏览器请求(从URL文本框输入)或刷新从服务器请求页面时,它工作正常.我的问题是当我切换到另一个页面并使用浏览器历史记录返回到home/index(定义了敲除模型)时,我得到没有敲除绑定的html.

有什么我可以忽略的吗?

更新:

在调试之后(做回历史记录)我能够看到document.ready方法被调用以及applyBindings方法,加载所有的敲除绑定.
看起来并非所有静态内容都被加载,就像图像一样.只有在jQuery completed()方法完成后,才会加载缺少的静态内容并撤消所有绑定.

更新2:

在挖掘了一些之后(二进制搜索html,每次删除一半代码以查看包是否被移除)我发现从我的html中删除一些元素解决了问题(引导选项卡和视频标记).有意义的是,选项卡可能会导致引导程序中出现未报告的错误,但我无法理解的是视频标记导致错误的原因.视频标记非常简单:

<video>
    <source src="/assets/Student_Resume1.mp4" type='video/mp4' />
</video>
Run Code Online (Sandbox Code Playgroud)

删除它解决了问题; 添加它会产生某种错误(我假设).当仅使用历史记录时(仅),视频未显示且敲除绑定失败.

更新3:

删除视频标记也无法解决问题,只会降低发生的可能性.这让我觉得它可能是由于页面过载或某种竞争条件造成的.

更新4:

我注意到从chrome控制台窗口再次调用ko.applyBindings,重新绑定绑定没有问题.因此尝试将applyBindings移动到$(window).load但没有成功.

更新5:

我也注意到视频标签在历史记录之后无法正常工作.chrome中的网络选项卡有3个视频请求.2获得了以下响应304 Not Modified,而第3个没有重播.

更新6:

在使用更多浏览器进行测试后,看起来它在firefox中没有发生.视频也没有加载,因为firefox不支持mp4.

Cou*_*ren 5

在使用application.js中的js dependancies之后,我注意到删除turbolinks(在rails 4 app中作为defualt)完全解决了问题,我通过从application.js中删除以下行来删除它:

//= require turbolinks
Run Code Online (Sandbox Code Playgroud)

并且绑定有效.所以再调查一下,我发现这篇 文章 指出:

"当您在JavaScript中使用document.ready时会出现一个问题,该事件仅在DOM完成加载时触发,但在Turbolinks执行页面更改时不会触发."

我理解Turbolinks在jquery ready方法之后更改页面状态的常见行为,并且在执行历史记录之后,我的applyBindings未在正确的时间(正常的jquery就绪)中应用.

为了正确触发applyBindings,我还必须将函数绑定到'page:load'.

所以我再次将turbolink添加到application.js并将正常的$(document).ready更改为如下所示:

var ready = function(){
    ko.applyBindings(new appViewModel());
};

$(document).ready(ready);
$(document).on('page:load', ready);
Run Code Online (Sandbox Code Playgroud)

绑定得到正确应用.

进一步阅读:

Github Turbolinks

RailsCast - Turbolinks