【问题标题】:Include Javascript on Certain Pages in Phoenix Framework Application在 Phoenix 框架应用程序的某些页面上包含 Javascript
【发布时间】:2016-08-06 09:51:52
【问题描述】:

我有一些 Javascript,我只想在我的 Phoenix 应用程序的某些页面中包含这些内容。

现在我已经在 myapp/web/templates/post/form.html.eex 的脚本标签中找到了 Javascript。

我知道我可以将 JavaScript 移至 web/static/js/app.js ...但我不想在每个页面上都包含 Javascript(仅在 2 个特定页面上需要)。

在我的应用程序的某些页面上加载这段 Javascript 而不重复代码和违反 DRY 原则的最佳方法是什么?

【问题讨论】:

  • 看看这个答案(render_existing 部分)stackoverflow.com/questions/32356096/…
  • 感谢 Gazler - 虽然不确定如何将这个答案应用于我的情况。你能在这里给我写一个答案吗?
  • 还要考虑在特定页面上运行 JS 与有条件地加载 JS 的概念。您可能不需要关心它是否/何时/何处加载,只需要它运行。这可以通过将Object.do_things() 调用包装在一个条件中来完成,以检查是否存在某个选择器(例如您的表单)。
  • @Todd 说得好,但在其他条件相同的情况下(通常不是),最好不要加载不会运行的代码。

标签: javascript elixir phoenix-framework


【解决方案1】:

1.

form.html.eex 中的所有 javascript 放入自己的文件中(可能类似于 js/posts.js)。

在底部添加:

export var Post = { run: function() {
  // put initializer stuff here
  // for example:
  // $(document).on('click', '.remove-post', my_remove_post_function)
}}

2.

在您的 app.html 中,在 <script src="#{static_path(@conn, "/js/app.js")}"></script> 下添加:

<%= render_existing @view_module, "scripts.html", assigns %>

3.

然后,在您的视图中(可能是 views/post_view.ex),添加如下方法:

def render("scripts.html", _assigns) do
  ~s{<script>require("web/static/js/posts").Post.run()</script>}
  |> raw
end

结论

现在 JavaScript 文件 post.js 只会在使用 post 视图时加载。

【讨论】:

    【解决方案2】:

    这是实现这一目标的一种方法。

    你在脚本标签中的 JavaScript,你把它移动到一个单独的文件中。

    您将“常规”javascript(将包含在每个页面中)和此自定义 javascript(将包含在某些特定页面中)划分为单独的目录。例如app/common/standard.js 和 app/custom/unique.js

    您将 brunch-config.js 修改为如下:

    module.exports = {
     files: {
        javascripts: {
          joinTo: {
            'custom.js': /^app[\\\/]common[\\\/][\S*?]\.js/,
            'app.js': /^app[\\\/]common[\\\/][\S*?]\.js/
            }
        }
    }
    

    然后你在所有页面中包含 app.js,

    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
    

    但 custom.js 仅在需要它的页面(或布局)模板中。

    <script src="<%= static_path(@conn, "/js/custom.js") %>"></script>
    

    【讨论】:

      【解决方案3】:

      另一种方法是使用特定于页面的类/元素。例如,app.js 中的以下代码将确保代码仅在 lesson/show 页面上执行,因为只有该页面具有 id 为 #lesson-container 的元素:

      import { startLesson } from './lesson/show.ts';
      
      if (document.querySelector('#lesson-container')) {
        startLesson();
      }
      

      【讨论】:

      • 请注意,这种方法是关于控制 JS 何时运行,而不是控制它是否加载
      【解决方案4】:

      这是基于Gazler's comment on the question 并且是一个the one submitted by cmititiuc 更普遍的答案。您不需要像在那个答案中那样包装特定于页面的 JavaScript 代码,也不需要在特定于页面的 script 元素中导入特定于页面的文件。

      布局模板

      在您的布局中使用Phoenix.View.render_existing/3,如下所示:

      <head>
        <%= render_existing @view_module, "scripts.html", assigns %>
      </head>
      

      ...或者这个:

      <head>
        <%= render_existing @view_module, "scripts." <> @view_template, assigns %>
      </head>
      

      对于第一个示例,如果相关视图模块存在一个"scripts.html" 模板,这将呈现一个模板。

      对于第二个示例,"scripts." &lt;&gt; @view_template 模板,例如scripts.form.html,如果存在就会被渲染。

      如果视图模块的“脚本”模板不存在,则页面 HTML 中不会输出任何内容。

      查看模块

      对于在布局模板中使用render_existing/3 的第一个示例,您需要将这样的代码添加到帖子视图模块中:

      def render("scripts.html", _assigns) do
        ~E(<script src="file.js"></script>)
      end
      

      ...第二次您将添加如下代码:

      def render("scripts.show.html", _assigns) do
        ~E(<script src="show-file.js"></script>)
      end
      
      def render("scripts.index.html", _assigns) do
        ~E(<script src="index-file.js"></script>)
      end
      

      详情

      render_existingrender 之间的区别在于,如果引用的模板不存在,前者不会引发错误(在这种情况下,页面 HTML 中也不会输出任何内容)。

      The ~E sigil 提供“源文件中的 HTML 安全 EEx 语法”并且类似于(在大多数情况下,甚至可能总是)来自cmititiuc's answer 的相应代码:

      ~s{<script>require("web/static/js/posts").Post.run()</script>}
      |> raw
      

      结论

      一般来说,对于您想要通过页面head(或body 的末尾)中的script 元素导入特定JavaScript 文件的任何页面,或链接CSS 文件,或执行任何操作对于页面输出的一部分,否则由布局处理,您可以在上面的布局模板中使用render_existing,然后在这些页面的视图模块中实现适当的render 子句。

      此外,您没有理由不能使用上述两个示例中的 both 之类的东西,因此对于任何视图模块及其模板,您都可以:

      • 所有视图模块模板(但不是整个应用程序的所有模板)包含一些脚本(或 CSS 文件或以其他方式操作布局模板中的 HTML 输出)李>
      • 只为一个模板包含一些脚本(或...)

      【讨论】:

        【解决方案5】:
        <script src="myscripts.js"></script>
        

        将您的代码放入一个新的 .js 文件中。在相关的 html 文件中包含带有源文件路径的脚本标记。

        【讨论】:

        • js文件在myapp/web/static/js/myscripts.js时的文件路径是什么?现在是这样,并且没有加载Javascript。
        • 可以通过&lt;script src="&lt;%= static_path(@conn, "/js/myscript.js") %&gt;"&gt;&lt;/script&gt;获取路径
        • 这个错误输出到:assign @conn not available in eex template.
        猜你喜欢
        • 2016-09-18
        • 2013-10-20
        • 2011-07-27
        • 1970-01-01
        • 2021-08-09
        • 2015-05-17
        • 2016-04-05
        • 1970-01-01
        • 2019-11-05
        相关资源
        最近更新 更多