使用带有涡轮连接的angularjs

Pav*_*vel 59 ruby-on-rails angularjs turbolinks

我试图在我的应用程序中使用带有turbolinks的Angularjs框架.页面更改后,它不会初始化新的eventlisteners.是否有任何方法使其工作?提前致谢!

fie*_*edl 125

AngularJS与Turbolinks

TurbolinksAnguluarJS都可以用来使Web应用程序响应更快,从某种意义上说,响应用户交互,网页上发生了某些事情而无需重新加载和重新呈现整个页面.

它们在以下方面有所不同:

  • AngularJS可以帮助您构建一个富客户端应用程序,您可以在其中编写许多在客户端计算机上运行的JavaScript代码.此代码使网站与用户交互.它使用JSON API与服务器端后端(即使用Rails应用程序)进行通信.

  • 另一方面,Turbolinks有助于使网站互动,而无需您编写JavaScript代码.它允许您坚持在服务器端运行的Ruby/Rails代码,并且仍然"神奇地"使用AJAX来替换,并因此仅重新呈现已更改的页面部分.

Turbolinks强大允许您使用这种功能强大的AJAX机制,而无需手动执行任何操作,只需编写Ruby/Rails代码,随着应用程序的增长,您可能需要集成一个JavaScript框架(如AngularJS).

特别是在这个中间阶段,您希望将AngularJS连续集成到您的应用程序中,一次只有一个组件,将Angular JS和Turbolinks一起运行是非常有意义的.

如何一起使用AngularJS和Turbolinks

使用回调手动引导Angular

在Angular代码中,您有一行定义应用程序模块,如下所示:

# app/assets/javascripts/angular-app.js.coffee
# without turbolinks
@app = angular.module 'MyApplication', ['ngResource']
Run Code Online (Sandbox Code Playgroud)

加载页面时运行此代码.但由于Turbolinks只是替换了页面的一部分并阻止了整个页面的加载,你必须确保,即使在Turbolinks完成了部分重新加载之后,角度应用程序也已正确初始化("bootstrapped").因此,用以下代码替换上面的模块声明:

# app/assets/javascripts/angular-app.js.coffee
# with turbolinks
@app = angular.module 'MyApplication', ['ngResource']

$(document).on 'turbolinks:load', ->
  angular.bootstrap document.body, ['MyApplication']
Run Code Online (Sandbox Code Playgroud)

不要自动引导

您经常在教程中看到如何使用ng-appHTML代码中的属性自动引导Angular应用程序.

<!-- app/views/layouts/my_layout.html.erb -->
<!-- without turbolinks -->
<html ng-app="YourApplication">
  ...
Run Code Online (Sandbox Code Playgroud)

但是,将此机制与上面显示的手动引导程序一起使用会导致应用程序自举两次,因此会使应用程序失效.

因此,只需删除此ng-app属性:

<!-- app/views/layouts/my_layout.html.erb -->
<!-- with turbolinks -->
<html>
  ...
Run Code Online (Sandbox Code Playgroud)

进一步阅读

  • 这个方法对我来说非常适合angularjs 1.0.6.但是在升级到angularjs 1.2.0.rc3之后,我通过turbolinks导航到新页面后在控制台中得到了这个:`未捕获错误:[ng:btstrpd]应用程序已经使用此元素"文档"启动了.显然一个元素只能[引导一次](https://github.com/angular/angular.js/commit/3ee744).将`angular.bootstrap(document,['YourApplication'])`更改为`angular.bootstrap("body",['YourApplication'])`似乎没有任何问题. (29认同)
  • "身体"对我不起作用,但是文件.身体.谢谢! (10认同)
  • 很棒的答案!如果使用Turbolinks 5,事件名称必须更改为`$(document).on"turbolinks:load", - > ...`.谢谢! (4认同)

jev*_*per 9

Turbolinks试图优化页面的渲染,并与AngularJS的正常引导相冲突.

如果您在应用的某些地方使用Turbolinks,而某些部分则使用Angular.我提出这个优雅的解决方案

指向angularapp(使用ng-app ="appname")的页面的每个链接都应具有以下属性:

<a href="/myapp" data-no-turbolink>Say NO to Turbolinks</a>.
Run Code Online (Sandbox Code Playgroud)

第二个 - 在Stackoverflow上提到通过处理page:load event显式重新加载/引导每个ng-app.我认为这是侵入性的,更不用说你可能会加载一些不在页面上的东西,从而浪费资源.

我个人使用了上述解决方案.

希望能帮助到你