是否有人知道如何在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>
我收到了一个错误。
答案 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>
答案 2 :(得分:-5)
您似乎并不理解文件的服务器处理与客户端(浏览器)处理之间的界限。
Rails处理文件并运行服务器端命令(如<%= .. %>
中的命令)。 然后输出文件并提供服务。浏览器接收此文件。您可以通过查看页面来源查看浏览器收到的内容。
浏览器运行页面的JavaScript。这包括Angular脚本。 JavaScript是与表达式绑定的东西。
因此,您无法将Angular表达式添加到服务器端代码块,因为浏览器永远不会看到服务器端块 - 只显示它们输出的内容。