在 Phoenix 框架应用程序的某些页面上包含 Javascript
Include Javascript on Certain Pages in Phoenix Framework Application
我有一些 Javascript 只想包含在我的 Phoenix 应用程序的某些页面上。
现在我在 myapp/web/templates/post/form.html.eex
.
的脚本标签中得到了 Javascript
我知道我可以将 JavaScript 移动到 web/static/js/app.js
...但我不想在每个页面上都包含 Javascript(仅在特定的 2 个页面上需要页)。
在我的应用程序的某些页面上加载 Javascript 的这一部分而不重复代码和违反 DRY 原则的最佳方法是什么?
<script src="myscripts.js"></script>
将您的代码放入新的 .js 文件中。在相关 html 文件中的文件路径中包含带有源的脚本标记。
这是实现此目的的一种方法。
你在脚本标签中的JavaScript,你把它移到一个单独的文件中。
您将 "regular" 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>
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 视图时加载。
另一种方法是使用特定页面 classes/elements。例如,app.js
中的以下代码将确保代码仅在 lesson/show
页面上执行,因为只有该页面具有 ID 为 #lesson-container
:
的元素
import { startLesson } from './lesson/show.ts';
if (document.querySelector('#lesson-container')) {
startLesson();
}
这是基于 and is a slightly more general answer than 。您不需要像在该答案中那样严格地包装特定于页面的 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." <> @view_template
模板,例如scripts.form.html,存在则渲染
如果视图模块的 'scripts' 模板不存在,则页面中不会输出任何内容 HTML。
查看模块
对于在布局模板中使用 render_existing/3
的第一个示例,您需要将如下代码添加到 post 视图模块:
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_existing
和 render
的区别在于,如果引用的模板不存在,前者不会引发错误(并且页面中不会输出任何内容 HTML在那种情况下也是如此)。
The ~E
sigil provides "HTML safe EEx syntax inside source files" and is similar to (in most cases, or maybe even always) the corresponding code from :
~s{<script>require("web/static/js/posts").Post.run()</script>}
|> raw
结论
一般来说,对于任何要通过页面 head
中的 script
元素(或 body
), 或 link CSS 文件,或对其中由布局处理的部分页面输出执行任何操作,您将在布局模板中使用 render_existing
如上所述,并且然后在这些页面的视图模块中实施适当的 render
子句。
此外,您没有理由不使用上面两个示例中的 both 这样的东西,这样对于任何视图模块及其模板,您都可以:
- 为所有视图模块包含一些脚本(或CSS文件或以其他方式操纵布局模板中的HTML输出)模板(但不是整个应用程序的所有模板)
- 仅为一个模板包含一些脚本(或...)
我有一些 Javascript 只想包含在我的 Phoenix 应用程序的某些页面上。
现在我在 myapp/web/templates/post/form.html.eex
.
我知道我可以将 JavaScript 移动到 web/static/js/app.js
...但我不想在每个页面上都包含 Javascript(仅在特定的 2 个页面上需要页)。
在我的应用程序的某些页面上加载 Javascript 的这一部分而不重复代码和违反 DRY 原则的最佳方法是什么?
<script src="myscripts.js"></script>
将您的代码放入新的 .js 文件中。在相关 html 文件中的文件路径中包含带有源的脚本标记。
这是实现此目的的一种方法。
你在脚本标签中的JavaScript,你把它移到一个单独的文件中。
您将 "regular" 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>
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 视图时加载。
另一种方法是使用特定页面 classes/elements。例如,app.js
中的以下代码将确保代码仅在 lesson/show
页面上执行,因为只有该页面具有 ID 为 #lesson-container
:
import { startLesson } from './lesson/show.ts';
if (document.querySelector('#lesson-container')) {
startLesson();
}
这是基于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." <> @view_template
模板,例如scripts.form.html,存在则渲染
如果视图模块的 'scripts' 模板不存在,则页面中不会输出任何内容 HTML。
查看模块
对于在布局模板中使用 render_existing/3
的第一个示例,您需要将如下代码添加到 post 视图模块:
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_existing
和 render
的区别在于,如果引用的模板不存在,前者不会引发错误(并且页面中不会输出任何内容 HTML在那种情况下也是如此)。
The ~E
sigil provides "HTML safe EEx syntax inside source files" and is similar to (in most cases, or maybe even always) the corresponding code from
~s{<script>require("web/static/js/posts").Post.run()</script>}
|> raw
结论
一般来说,对于任何要通过页面 head
中的 script
元素(或 body
), 或 link CSS 文件,或对其中由布局处理的部分页面输出执行任何操作,您将在布局模板中使用 render_existing
如上所述,并且然后在这些页面的视图模块中实施适当的 render
子句。
此外,您没有理由不使用上面两个示例中的 both 这样的东西,这样对于任何视图模块及其模板,您都可以:
- 为所有视图模块包含一些脚本(或CSS文件或以其他方式操纵布局模板中的HTML输出)模板(但不是整个应用程序的所有模板)
- 仅为一个模板包含一些脚本(或...)