我正在使用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());
});
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 %>
当我通过正常的浏览器请求(从URL文本框输入)或刷新从服务器请求页面时,它工作正常。 我的问题是当我切换到另一个页面并使用浏览器历史记录返回到home / index(定义了敲除模型)时,我得到没有敲除绑定的html。
我有什么东西可以忽略吗?
更新
经过调试(回溯历史记录)后,我能够看到document.ready方法被调用,还有applyBindings方法,加载所有的敲除绑定。
看起来并非所有静态内容都被加载,就像图像一样。只有在完成jQuery completed()方法之后,才会加载缺少的静态内容并撤消所有绑定。
更新2:
在挖掘了一些之后(二进制搜索html,每次删除一半代码以查看包是否被删除)我发现从我的html中删除一些元素解决了问题(引导标签和视频标签)。有意义的是,选项卡可能会导致引导程序中出现未报告的错误,但我无法理解的是视频标记导致它的原因。 视频标记非常简单:
<video>
<source src="/assets/Student_Resume1.mp4" type='video/mp4' />
</video>
删除它可以解决问题;添加它会产生某种错误(我假设)。当仅使用历史记录时(仅),视频未显示且敲除绑定失败。
更新3:
删除视频代码也无法解决问题,只会降低发生的可能性。 这让我觉得它可能是由于页面过载或某种竞争条件造成的。
更新4:
我注意到从chrome控制台窗口再次调用ko.applyBindings,重新绑定绑定没有问题。所以试图将applyBindings移动到$(window).load但没有成功。
更新5:
我也注意到历史记录后视频标签无效。 chrome中的网络选项卡有3个视频请求。 2获得了以下响应304 Not Modified,而第3个没有重播。
更新6:
在使用更多浏览器测试之后,看起来它在firefox中没有发生。视频也没有加载,因为firefox不支持mp4。
答案 0 :(得分:5)
在app.js中使用js dependancies后, 我注意到删除turbolinks(在rails 4 app中作为defualt)完全解决了问题,我通过从application.js中删除以下行来删除它:
//= require turbolinks
绑定工作正常。 所以调查了一些,我发现了这一点 Article 声明:
“在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);
正确应用绑定。
进一步阅读: