Ruby on rails 将angularjs与TurboLink一起使用
我正在尝试在我的应用程序中使用Angularjs框架和TurboLink。页面更改后,它不会初始化新的eventlisteners。有什么办法可以让它工作吗?提前谢谢 Turbolinks对于客户端MVC框架没有太大意义。TurboLink用于从服务器响应中除去除正文以外的所有内容。使用客户端MVC,您应该只向客户端传递JSON,而不是HTML 在任何情况下,TurboLink都会创建自己的回调Ruby on rails 将angularjs与TurboLink一起使用,ruby-on-rails,angularjs,turbolinks,Ruby On Rails,Angularjs,Turbolinks,我正在尝试在我的应用程序中使用Angularjs框架和TurboLink。页面更改后,它不会初始化新的eventlisteners。有什么办法可以让它工作吗?提前谢谢 Turbolinks对于客户端MVC框架没有太大意义。TurboLink用于从服务器响应中除去除正文以外的所有内容。使用客户端MVC,您应该只向客户端传递JSON,而不是HTML 在任何情况下,TurboLink都会创建自己的回调 page:load page:fetch page:restore page:change Ang
page:load
page:fetch
page:restore
page:change
AngularJS vs.Turbolinks
Turbolinks和AnguluarJS都可以用于使web应用程序响应更快,因为响应用户交互时,网页上会发生一些事情,而无需重新加载和重新提交整个页面
它们在以下方面有所不同:
- AngularJS帮助您构建一个富客户端应用程序,您可以在该应用程序中编写大量在客户端计算机上运行的JavaScript代码。此代码使站点与用户交互。它使用JSON API与服务器端后端通信,即与Rails应用程序通信
- 另一方面,Turbolinks有助于使站点具有交互性,而无需编写JavaScript代码。它允许您坚持使用在服务器端运行的Ruby/Rails代码,并且仍然“神奇地”使用AJAX替换页面中已更改的部分,并因此重新呈现
# app/assets/javascripts/angular-app.js.coffee
# without turbolinks
@app = angular.module 'MyApplication', ['ngResource']
此代码在加载页面时运行。但由于Turbolinks只是替换了页面的一部分,并阻止了整个页面的加载,因此您必须确保angular应用程序已正确初始化(“引导”),即使Turbolinks完成了部分重新加载。因此,用以下代码替换上述模块声明:
# app/assets/javascripts/angular-app.js.coffee
# with turbolinks
@app = angular.module 'MyApplication', ['ngResource']
$(document).on 'turbolinks:load', ->
angular.bootstrap document.body, ['MyApplication']
不要自动引导
您经常在教程中看到如何通过在HTML代码中使用ng app
属性自动引导Angular应用程序
<!-- app/views/layouts/my_layout.html.erb -->
<!-- without turbolinks -->
<html ng-app="YourApplication">
...
进一步阅读
- AngularJS引导:
- TurboLink上的Railscasts(解释回调):
- 演示应用程序:
bootstrapAngular = ->
$('[ng-app]').each ->
module = $(this).attr('ng-app')
angular.bootstrap(this, [module])
$(document).on('page:load', bootstrapAngular)
Javascript:
function bootstrapAngular() {
$('[ng-app]').each(function() {
var module = $(this).attr('ng-app');
angular.bootstrap(this, [module]);
});
};
$(document).on('page:load', bootstrapAngular);
这将导致在TurboLink加载每个页面后启动angular应用程序
归功于该插件可以通过ng应用程序指令触发模块引导。如果您试图手动引导模块,jquery.turbolinks可能会导致ng:btstrpd错误。我发现的一个警告是jquery.turbolinks依赖于page:load
事件,它可以在任何新的特定于页面的
标记完成运行之前触发。如果在application.js之外包含模块定义,这可能会导致$injector:nomod
错误。如果您确实希望在单独的javascript文件中定义模块,并且这些文件只包含在特定页面上,那么您可以通过data no turbolink
在指向这些特定页面的任何链接上定义模块,以防出现错误
未捕获错误:[ng:btstrpd]应用程序已使用此命令启动
元素“文档”
升级到angular 1.2.x后,您可以使用下面的方法来修复此问题
angular.module('App').run(function($compile, $rootScope, $document) {
return $document.on('page:load', function() {
var body, compiled;
body = angular.element('body');
compiled = $compile(body.html())($rootScope);
return body.html(compiled);
});
});
在之前的博文中,@nates建议将
angular.bootstrap(文档,['YourApplication'])
更改为angular.bootstrap(“正文,['YourApplication'])
,但这会导致未编译内容的闪烁。Turbolinks试图优化页面呈现,并与AngularJS的正常引导冲突
如果您在应用程序的某些位置使用TurboLink,并且某些部分使用Angular。我建议这个优雅的解决方案:
指向angularapp(使用ng app=“appname”)页面的每个链接都应具有以下属性:
<!-- app/views/layouts/my_layout.html.erb -->
<!-- with turbolinks -->
<html>
...
<a href="/myapp" data-no-turbolink>Say NO to Turbolinks</a>.
。
Stackoverflow中提到的第二个问题是通过处理page:load事件显式地重新加载/引导每个ng应用程序。我认为这是侵入性的,更不用说你可能会加载一些不在页面上的东西,从而浪费资源
我个人使用了上述解决方案
希望它能有所帮助根据我看到的评论,如果Angular与TurboLink冲突(例如我允许Angular处理一些路由),那么将两者结合使用的唯一有效方案是,如果我有一个正在尝试移植到Angular的现有应用程序 就我个人而言,如果我从头开始做这件事,我认为最好的解决方案是决定什么应该处理路由并坚持下去。如果是角度的,那么就不要使用Turbolinks->如果你有一个接近单页应用程序的东西,这对你没有多大帮助。如果允许Rails处理路由,那么只需使用Angular来组织服务器在提供模板时无法处理的客户端行为 我是不是错过了一个场景?在我看来,试图在不同的框架之间划分路由责任似乎并不优雅,即使在大型应用程序中也是如此。。。除了刷新页面或导航到新路线之外,Turbolinks还会干扰AngularJS吗?同时使用Turbolinks和AngularJS +1到@fiedl获得一个很好的答案。但我更喜欢利用
function boostrapAngularJS () {
angular.bootstrap(document.body, ['My Application']);
addCallbackToPageChange();
}
function addCallbackToPageChange() {
angular.element(document).one('page:change', function () {
angular.element(this).one('page:load', boostrapAngularJS);
});
}
addCallbackToPageChange();
<html>
<body ng-app=“yourApplicationModuleName">
</body>
</html>