rails中link_to内的角度表达式

时间:2015-01-08 18:23:27

标签: ruby-on-rails ruby angularjs

是否有人知道如何在rails中的link_to中插入角度表达式。

<section ng-controller="listServiceCtrl">   
    <ul ng-repeat="service in servicelist">
        <li><%= link_to '{{ service.service}}', home_user_path('{{ service.id}}') %></li>
    </ul>
</section>

我收到了一个错误。

3 个答案:

答案 0 :(得分:10)

如果你查看link_to()的rails文档,他们就会这样说:

link_to "Profile", profile_path(@profile)

# => <a href="/profiles/1">Profile</a>

所以如果你写:

<%= link_to '{{ service.service}}', ..... %>

...你会得到字符串:

"<a href=....>{{ service.service}}</a>"

...这正是你想要在你的angularjs的html中得到的。到目前为止,非常好。

接下来,路径助手的rails指南显示了这一点:

  

如果资源:照片 [在config / routes.rb中]:

     

photos_path 返回/照片

     

new_photo_path 返回/ photos / new

     

edit_photo_path(:id)返回/ photos /:id / edit(例如,    edit_photo_path(10)返回/照片/ 10 /编辑)

     

photo_path(:id)返回/ photos /:id(例如,photo_path(10)   返回/照片/ 10)

代码中的以下路径助手:

home_user_path(3)

...看起来它与上面最后一个路径助手的格式相匹配。你的模特名为HomeUser吗?如果是,那么以下内容:

home_user_path(3)

将返回字符串:

"/home_users/3"

好。但是有可能写下来:

home_user_path('hello')

参数必须是数字吗?字符串参数会产生错误吗?事实证明,上面的行返回字符串:

"/home_users/hello"

因此,看起来您可以使用任意字符串作为rails路径助手的参数。但是,如果您在视图中尝试以下操作:

<% my_href = home_user_path('{{ service.id}}') 
   puts "*** #{my_href}"
%>

...然后加载页面,然后查看显示服务器输出的终端窗口,然后向上滚动,您将看到:

*** /home_users/%7B%7B%20service.id%7D%7D

到底是什么?如果仔细观察,你可以看出service.id这个文字,但两边的那些胡言乱语是什么?如果您有足够的经验,则会将其识别为 url encoding 。网址只能包含某些字符,如果您需要在网址中包含非法字符,则必须网址转义。 url转义可以通过前导%符号识别。很明显,home_user_path()是url在返回url字符串之前转义字符{{}}。如果您检查合法网址字符列表,则不包括大括号 - 因此,大括号必须在显示在网址中时进行转义。因此,rails path helper会自动转义url中的非法字符 - 这通常是一个不错的功能。

当然,当用作<a>标记中href属性的值时,angularJS无法识别url转义为乱码。但是,有一种方法可以反转url转义。鉴于字符串:

"/home_users/%7B%7Bservices.id%7D%7D"

你可以 unescape 字符串来获取原始字符串。执行 url unescaping 的ruby方法在Ruby标准库中:

ruby 1.9: CGI::unescape()

ruby 2.0: URI::unescape()
          URI::decode_www_form_component() <--Use this one!  Even though its name is confusing, it's more reliable.  See: https://www.ruby-forum.com/topic/207489

ruby 2.2: URI::decode_www_form_component()  

(我实际上将在下面的讨论中使用URI :: unescape()来使事情变得更清楚 - 新方法的名称太长而且令人困惑。)

显然,rails为你做了'uri'(或者需要'cgi'),所以你可以在视图中调用方法。如果你尝试:

<% url_escaped_href = home_user_path('{{ service.id}}') 
   my_href = URI::unescape(url_escaped_href)

   puts "*** #{my_href}"
%>

...您将在服务器窗口中看到以下内容:

*** /home_users/{{ service.id}}

...当然,这是您想要的<a>标记中href属性的值。因此,您可以写:

<%= link_to '{{ service.service}}', 
            URI::unescape( home_user_path('{{ service.id}}') ) 
%>

或等效地:

<% url_escaped_href = home_user_path('{{ service.id}}') 
   my_href = URI::unescape(url_escaped_href)
%>

<%= link_to '{{ service.service}}', my_href %>

,这将产生字符串:

<a href="/home_users/{{service.id}}">
   {{service.service}}
</a>

然后,当html文件发送到您的浏览器时(注意文件只是一个大字符串),您的浏览器会将<a>标记识别为html,渲染它。然后当浏览器在页面上执行javascript时,angularJS将执行其魔法并用javascript变量的值替换双重curlies。

一个问题:在angularJS有机会用值替换double curlies之前,链接可能会显示。如果发生这种情况,并且用户点击该链接,他们将收到404 / Page Not Found错误。使用ng-href属性的优点是,在angularJS有机会用双值替换值之后才会显示链接。因此,您可能希望放弃使用rails link_to()表单帮助程序并手动构建链接标记,类似于Rimian发布的内容:

  <% url_escaped_href = home_user_path('{{ service.id}}') 
     my_href = URI::unescape(url_escaped_href)
  %>

  <div>
  <a ng-href="<%= my_href %>">{{service.service}}</a>
  </div>

答案 1 :(得分:1)

您可以修改rails路由器,以便它知道该怎么做:

<a ng-href="<%= home_users_path %>?id={{service.id}}">{{service.service}}</a>

https://docs.angularjs.org/api/ng/directive/ngHref

答案 2 :(得分:-5)

您似乎并不理解文件的服务器处理与客户端(浏览器)处理之间的界限。

Rails处理文件并运行服务器端命令(如<%= .. %>中的命令)。 然后输出文件并提供服务。浏览器接收此文件。您可以通过查看页面来源查看浏览器收到的内容。

浏览器运行页面的JavaScript。这包括Angular脚本。 JavaScript是与表达式绑定的东西。

因此,您无法将Angular表达式添加到服务器端代码块,因为浏览器永远不会看到服务器端块 - 只显示它们输出的内容。