开发者

Coffee script definitions get ignored when using :remote => true and js.erb-responses

Okay, consider the following: A app/views/pages/index.html.erb, consisting of:

<div id='content'>    
  <%= link_to 'Test', get_page_path('test'), :remote => true %>
</div>

A definition in app/controllers/pages_controller.rb like this:

def get
  @page = Page.new(:title => '404', :content => '<strong>Page not found</strong>') unless @page = Page.find_by_title(params[:title])
  respond_to do |format|
    format.html
    format.js
  end
end

A javascript asset in app/assets/javascripts/pages.js.coffee like this:

bork = (swedish) -> alert swedish
$ ->
  bork 'bork bork'

And finally a app/views/pages/get.js.coffee like this:

bork 'Smoerrebroed'
$('#content').html '<%= escape_javascript(@page.content).html_safe %>'

So, here's the fun part - I do see the 'bork bork' alert once as expected. However, after clicking on the link, only the content gets replaced (as indicated by the second line), I don't see a 'Smoerrebroed' alert. The pages.js.coffee stuff is obviously included - but seems to be inaccessible outside the page itself. As such, the compartmentalization Rails is doing is not very useful - why exactly should I put my 'pages controller' specific stuff into pages.js.coffee when it is only accessible inside that specific script? Is there any way to work around开发者_如何学JAVA that? It seems to based on the fact that coffee script wraps everything inside a

(function() {
  //specific stuff here
}).call(this);

which supposedly is there to prevent the script from executing before the page has loaded. Is there some way of telling coffeescript to stop doing that because I'm using the $ ->(shorthand) or $(document).ready() function anyway...


You say that the CoffeeScript function wrapper

supposedly is there to prevent the script from executing before the page has loaded.

That's actually the second time today this misconception has come up, so I'll point you to my earlier answer on the question Coffeescript, Backbone and load order.

To address the main part of your question: Yes, it is possible to turn off the wrapper (globally), but certainly not recommended. See How can I use option "--bare" in Rails 3.1 for CoffeeScript?

What you should do instead is make bork a global function. Either attach it to window or, as a shorthand, use @ (since this/@ points to window in the outer context), i.e.

@bork = (swedish) -> alert swedish

Learn to see the function wrapper as a blessing, not a curse—it means that if your team happens to define things called bork in two different files, they won't overwrite each other, unless they're both explicitly made global. It's not just a CoffeeScript-ism; using a function wrapper around each file to avoid polluting the global namespace is considered a good JavaScript practice. jQuery, for instance, does it in each of its several component modules.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜