Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails javascript assets behaving oddly depending on routing

I'm currently learning Rails, and I'm wanting to use angular in my project.

Here's a simple application from scratch.

1). Create a new rails app:

rails new hello_rails

2). Add angular gem to Gemfile

gem 'angularjs-rails'

3). Install the bundle

bundle install

4). Add angular to javascript manifest in app/assets/javascripts/application.js

//=require angular

5). Generate welcome index

rails generate controller welcome index

6). Populate index.html.erb with an angular hello world

 <div style = "background-color: grey">
    this is index.html.erb<br>

  <div ng-app="">
    <p>Name : <input type="text" ng-model="name"></p>
    <h1>Hello {{name}}</h1>
</div>

</div>

7). Also modify application.html.erb

<pre>
<!DOCTYPE html>
<html>
<head>
  <title>HelloRails</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body style = "background-color:green">

  This is application.html.erb <br>

   <%= link_to "click here to go home", root_path %> <br>

A yeild statement is below: <br>
<%= yield %>

</body>
</html>

8). Set root route to welcome#index in config/routes.rb

root 'welcome#index'

Run this - this works fine.

Here's what we get:

enter image description here

The angular is working:

enter image description here

However, if I click the link to return to root_path it stops working

enter image description here

Additionally, if we add some angular to our application.html.erb the yielded angular stops working.

<div ng-app="">
<p>Name : <input type="text" ng-model="home_name"></p>
<h1>Hello {{home_name}} at home</h1>
</div>

enter image description here

Can you explain why rails is working this way?

like image 528
dwjohnston Avatar asked Oct 19 '22 22:10

dwjohnston


1 Answers

I followed your steps and configured angular the same way you did. I removed turbolinks and this solved the first problem. The second problem was due to wrong usage of the ngApp directive.

AngularJS ngApp documentation

The ngApp directive designates the root element of the application and is typically placed near the root element of the page

and

Only one AngularJS application can be auto-bootstrapped per HTML document.

That said. You have ng-app="" twice in your code. And since one application only can be bootstrapped, the first div containing angular code in your application.html.erb would work but the other in index.html.erb would not.

The solution to your problem is place ng-app="" on your <body> or <html> tags in your application.html.erb according to your needs. (If you want angular to manipulate tags in the <head> section like page <title> for example just place ng-app="" on your <html> tag. If not just place it on your body tag.

<pre>
<!DOCTYPE html>
<html>
<head>
  <title>HelloRails</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body style = "background-color:green" ng-app="">

  This is application.html.erb <br>
  <div>
    <p>Name : <input type="text" ng-model="home_name"></p>
    <h1>Hello {{home_name}} at home</h1>
  </div>

   <%= link_to "click here to go home", root_path %> <br>


A yeild statement is below: <br>
<%= yield %>

</body>
</html>

Manipulating page title by placing ngApp in <html>

<html  ng-app="">
<head>
  <title>{{home_name}} | HelloRails</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
...

Works like a charm!

After adding ngApp to body tag

Here are some resources for using Angular with Rails and correctly configure turbolinks with Angular. Resource 1
Resource 2

like image 131
Oss Avatar answered Nov 03 '22 06:11

Oss