2011-03-08 53 views
4

我试图让轨道将目录的内容推送到Haml(作为字符串数组)并将它们呈现为链接文件名作为链接文本,但无法弄清楚如何传递多个实例变量到我的Haml文件。 这里是我的控制器代码:将多个变量传递给Rails中的Haml文件?

class FilesController < ApplicationController 
    def index 
    @dir = Dir.new('/Users/userName/Code/RailsTest/public/'); 
    @files = Dir::entries('/Users/userName/Code/RailsTest/public/'); 
    @fileNames = @files; 
    for file in @files 
     file = @dir.path + '/' + file 
    end 
    respond_to do |format| 
     format.html # index.html.haml 
     #format.xml { render :locals {:files => @files, :fileNames: @fileNames} } 
     format.xml { render :xml => @files } 
    end 
    end 
end 

和我Haml的文件:

%h1 Files 
%p This will eventually list the files in our upload directory 

- @files.each do |file| 
    %a(href=file) file 

感谢能给予任何帮助!

编辑: 我控制器的方法现在包含

@dir = Dir.new('/Users/chronon/DEsktop/RailsNexus/public'); 
    @files = Dir::entries('/Users/chronon/DEsktop/RailsNexus/public'); 
    @fileNames = @files; 
    @files.map! do |file| 
     {:path => "#{@dir.path}/#{file}", :filename => file} 
    end 
    respond_to do |format| 
     format.htm 
    end 

而且两者index.html.haml和_file_link.html.haml如nzifnab建议。 不过,现在我得到“。不能符号转换成整数”错误在我_file_link文件

两个HAML文件的内容是

%h1 Files 
%p This will eventually list the files in our upload directory 

= render :partial => 'files/file_link', :collection => @files, :as => :file 

= link_to(:file[:path], :file[:filename]) 

(我不得不改变‘文件’到‘:文件’为使正常工作基于该电源轨的导游)

回答

2

什么有两种方法可以做到这一点:渲染它作为一个汉邦al或渲染正常输出模板。如果将其渲染为部分,则可以传递一个:locals选项哈希,您可以使用它来获取变量。如果你渲染一个正常的haml文件,那么你将需要为数据使用实例变量。

我会在你的控制器改变for循环的:

@files.map! do |file| 
    {:path => "#{@dir.path}/#{file}", :filename => file} 
end 

编辑:刚刚意识到你可能是未使用的.MAP!方法。它会遍历@files中的每个条目,并将其值更改为块中最后一行。如果你使用.map而不是.map!那么方法将返回一个由这些值组成的新数组。

这只是一个更像ruby的样子,而且我并不是100%确定您正在使用的for循环是否像您打算的那样通过引用来改变值。再次,也许你的很好......但我喜欢像Array.map,Array.each等ruby-like方法,而不是for语法,这可以让你获得每个对象所需的所有数据。

你HAML文件可以进行如下更改:

index.html.haml

%h1 Files 
%p Something exciting 

= render :partial => 'files/file_link', :collection => @files, :as => :file 

,这会使得文件files/file_link.html.haml曾经为@files阵列中发现的每一个对象,并保存该对象在局部变量file:as =>选项所指定。

然后你就可以有这样的文件:

_file_link.html.haml

= link_to(file[:path], file[:filename]) 

你在你的控制器定义的任何实例变量会自动在视图中可用。如果无论出于什么原因,您希望将视图中的对象变为局部变量,我相信您必须将视图呈现为部分视图而不是全视图。虽然它可能会这样做,我不是100%肯定。:

format.html{ render :action => 'index', :locals => {:files => files} } 

但是,这并不是很好的做法。在视图中直接使用来自控制器的实例变量是很典型的。希望我在这里的某个地方回答你的问题:)(format.html你没有选项或参数就足以满足我上面发布的视图代码)。

编辑:

你是正确的改变render :partial to, :as => :file(这里的象征,我更新了它上面)。但是,它的作用是将@files数组中的每个项目作为一个名为file的新局部变量发送给partial。所以,你应该部分还是说:

= link_to(file[:path], file[:filename]) 

也请记住,你不需要你@fileNames实例变量了。 .map!和散列修复了这个问题给你。

为了澄清,你叫@files.map! do ......等等等等,你的数据结构应该是这个样子后:

@files = [ 
    {:path => "my/path/1/filenamex", :filename => "filenamex"}, 
    {:path => "my/path/2/filenamey", :filename => "filenamey"}, 
    {:path => "my/path/3/filenamez", :filename => "filenamez"} 
] 

因此,当你发送变量render :partial =>这是要为每个渲染一次那些哈希。第一渲染,它会在_file_link.html.haml设置file变量这样:

{:path => "my/path/1/filenamex", :filename => "filenamex"} 

它将三次通过它为每个哈希值。

我希望你明白这是怎么回事:)

+0

它的工作原理,除了在我的index.html.haml文件中的“未定义的局部变量或方法'文件'”的错误。我用更好的描述更新了我的问题。非常感谢! – Tim 2011-03-08 23:19:07

+0

@Tim我编辑了我的答案,以反映你自己的编辑。让我知道这是否有帮助,或者如果你需要澄清。最好你理解*为什么*有些东西在起作用,而不是仅仅复制粘贴代码并说“我已经完成了” – nzifnab 2011-03-09 00:59:17

+0

完美的工作,我相信我明白了为什么以及我以前出错的地方。谢谢! – Tim 2011-03-09 16:40:37

0

认为这是你想要

@myfiles = []; 
    for file in @files 
      @myfiles << { :file => @dir.path + '/' + file, :filename => file} 
    end 

    respond_to do |format| 
     format.html 
    end