0

我对 aresource和一些特定于它的 javascript 有一个看法。所以,我尽职尽责地将 Javascript 放入app/assets/javascripts/resource.js.coffee.

问题是,当我转到应用程序中的其他视图时,会出现各种 Javascript 错误,例如:

Type issue: 'null' is not an object...

page_url = page_image.getAttribute('src');

应用程序工作正常,但这些脚本实际上不应该尝试在它们不打算用于的视图中运行。

显然我错过了一些东西......嗯......很明显!它是什么?

4

3 回答 3

2

默认情况下,application.js包括 中的所有脚本app/assets/javascripts,并且默认情况下,您的布局包括所有这些脚本。这样做的好处是浏览器只需对 Javascript 文件发出一次请求,然后可以缓存这些文件——但缺点是所有 Javascript 都在每个页面上运行。

有两个基本的解决方案:

  1. 编写 Javascript,在需要时执行它应该执行的操作,而在不需要时不执行任何操作。
  2. 更改application.js为不包含所有内容,在需要时包含单个 Javascript 文件,并更改config.assets.precompile为包含所有新的顶级文件。
于 2012-09-21T18:29:44.253 回答
1

只有在某些页面上运行一些 javascript,rails 中没有任何内容。我采取的方法是基于这篇文章

我的每个页面特定的咖啡脚本文件看起来像

window.App.controller_name = 
  init: ->
    #stuff that happens for all actions
  edit: ->
    #Stuff that happens only for the edit action

body 元素装饰有 data-controller 和 data-action 属性。application.js 中的一些 javascript 然后运行适当的 javascript:

execute_hook = (controller, action='init') ->
  ns = window.App
  if controller?
    if ns[controller] && typeof(ns[controller][action]) == "function"
      ns[toplevel][controller][action]()

jQuery ->
  body = document.body
  controller = body.getAttribute("data-controller")
  action = body.getAttribute("data-action")
  execute_hook(controller)
  execute_hook(controller, action)
于 2012-09-21T19:16:26.350 回答
0

两个建议,第一个是hacky,第二个很棒。

1.清单+布局

为需要不同 JS 组合的视图创建一个新的 JS 清单文件,从新布局调用该清单文件,并从呈现这些视图的控制器操作调用新布局。

在您的示例中:

应用程序/资产/javascripts/resource.js.coffee

// Requires
//= require_whatever_js_files_your_resource_page_needs_here

// Custom JS below
...

应用程序/视图/布局/resource.html.erb

...
<%# Within your <head> tag %>
<%= javascript_include_tag "resource" %>
...

应用程序/控制器/resources_controller.rb

class ResourceController < ApplicationController
# filters, default layout, other actions, etc.
...

# Your action that needs only the resource JS,
# and therefore the resource layout
def action_that_only_uses_resource_js
  @some_objects = SomeObjects.all
  render layout: 'resource' # <- This is the important part
end

显然,这种方法不能很好地扩展,因为它不够灵活,也就是说,你不能随意组合你的 JS,而且毫无疑问会需要。这使我们将您的 JS 分解为...

2. RequireJs 模块

使用这个 gem将RequireJs集成到 Rails 中。您将获得所需的模块化并防止发生冲突。RequireJs 采用了AMD 模式,我相信这正是您正在寻找的。

于 2012-09-22T03:30:43.753 回答