Magento 2 - Alan Storm 博客 - 初始化 JavaScript
Magento 2 - Alan Storm 博客 - 初始化 JavaScript
https://alanstorm.com/magento_2_javascript_init_scripts/
今天我们探索的是 Magento 2 中几种不同的方法,不用插入
到这里,我们创建了一个单模块依赖的 RequireJS 模块。这个依赖就是我们创建的模块(Pulsestorm_JavascriptInitTutorial/example)。
在你的系统中加载 http://magento.example.com/pulsestorm_javascriptinittutorial/ 这个URL ,你会看到这个提示信号。
如果对以上内容不熟悉,你可能需要浏览一下 Magento 2 and RequireJS 这篇文章。
X-Magento-Init
我们将讨论的第一个初始化方法是
修改后重新加载页面,你回看到来自 example.js 的 alter 声明。
如果你之前没有见过这种语法,他可能看起来有点陌生。那我们分开来看。
首先是
这个标签不是 JavaScript 标签。注意 type="text/x-magento-init" 这个属性。当浏览器在 script 标签的类型中没有认出这个值时,它将会忽略这个标签的内容。Magento(跟其他现在的 JavaScript 框架相似)充分利用这一特点。运行的 Magento JavaScript 代码扫描带有 text/x-magento-init 的 script 标签,但是这个不在本文讨论。如果你想自己探索,这个回答是个不错的开始。
我们即将讨论 x-magento-init 代码的另一部分是:
#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml
{
"Pulsestorm_JavascriptInitTutorial/example":{}
}
Magento 将会查询这个对象的 key ,并且把他当作一个 RequireJS 模块。这就是如何加载 example.js 脚本了。
你可能想知道为什么这个对象没有值。你可能也想知道为什么这整个对象是另一个 key 为 * 的对象的一部分:
#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml
{
"*": {/*...*/}
}
在我们讨论这个之前,我们需要讨论 JavaScript 组件。
Magento JavaScript 组件
以上的例子是把 RequireJS 模块当作一段程序来执行。这个可以使用,并且Mangento 自己经常使用 x-magento-init 方法来调用 RequireJS 模块的程序。然而,x-magento-init 的真正的作用是创建一个 Magento JavaScript 组件。
Magento Javascript 组件是返回值为 function 的 RequireJS 模块。Magneto 的系统代码将会以特定的方式调用,展示了额外的功能。
如果你不明白,试着按照以下内容改变你的 RequireJS 模块:
//File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/web/example.js
define([], function () {
var mageJsComponent = function()
{
alert("A simple magento component.");
};
return mageJsComponent;
});
这里,我们定义了一个方法,并把它赋值给了名为 mageJsComponent 的变量,然后返回这个变量。
把以上内容放在适当的位置,如果你重新加载页面,应该回看到一个内容为 A Simple Magento Component 的警告框。
这可能看起来很傻,如果Magneto 所做的都是调用它,那返回一个方法的意义是什么呢?你是对的,但是这因为我们还落下了一些东西。按照以下内容试着更改你的 phtml 模板:
#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtmlHello WorldGoodbye World
并且,改变 RequireJS 模块:
//File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/web/example.js
define([], function () {
var mageJsComponent = function(config)
{
alert("Look in your browser's console");
console.log(config);
//alert(config);
};
return mageJsComponent;
});
如果你重新加载页面,你应该可以看到改变后的警告信息。如果你查看浏览器 Javascript 控制台,应该也会看到:
> Object {config:"value"}
当我们创建了一个 Magento Javascript 组件,Mangento 调用返回的方法,并且包含了来自 text/x-magento-init 的对象。
"Pulsestorm_JavascriptInitTutorial/example":{"config":"value"}
这就是为什么 RequireJS 模块名字是一个 key -- value 是我们想要传入组件的对象。
在这些例子中,这可能是一个有点傻的抽象概念。然而,在真实的模块中,我们将会用 PHP 生成 JSON 。这个系统允许我们在 phtml 模板中渲染 JSON ,然后把他们传入 Javascript 代码中。这个有利于避免直接用 PHP 生成 Javascript 而造成的代码混乱、意外的错误和安全问题。
在结束 x-magento-init 之前,还要讨论最后一个特点。你将会记得我们说过的:
- 提供一种给这个代码传入服务器端生成的 JSON 对象方式
- 提供一种给这个代码提供执行的 DOM 节点方式
我们已经描述了如何传入服务器端生成的 JSON,但是 DOM 节点怎么传入呢?
按照以下内容改变你的 RequireJS 模块:
//File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/web/example.js
define([], function () {
var mageJsComponent = function(config, node)
{
console.log(config);
console.log(node);
//alert(config);
};
return mageJsComponent;
});
这里,我们所做的是给 mageJsComponent 方法添加了第二个参数。这第二个参数就是我们想要程序执行的 DOM 节点。然而,如果你冲洗加载这个页面,你可以在控制台看到:
> Object {config:"value"}
> false
Magento 确实传入了一个 node 值,但是这个值是 false,从哪里来的?
Well,Magento 不可能知道我们想要在哪个 DOM 节点上执行,我们需要告诉他,更改你的 phtml 模板:
#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtmlHello WorldGoodbye World
这里,我们把 * 改变成了 #one 。我们之前使用的 * 实际上是一个程序不需要指定 DOM 节点的特殊情况,这个对象的 key 实际上是一个 CSS/jQuery 样式的选择器,它告诉 Magneto 程序 Pulsestorm_JavascriptInitTutorial/example 应该在哪个 DOM 节点上执行。如果我们重新加载页面,我们可以在控制台看到:
> Object {config: "value"}
> Hello World
ID 也是不限制的,你也可以使用 CSS 类:
#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml
".foo": {
"Pulsestorm_JavascriptInitTutorial/example":{"config":"value"}
}
你可以在控制台看到:
> Object {"config":"value"}
> Hello World
> Object {"config":"value"}
> Goodbye World
通过建立这种系统,Magneto 鼓励开发者避免把 DOM 节点生硬地写到 RequireJS 模块中。x-magento-init 意味着有一个系统级别的方法来建立依赖服务器生成的 JSON 的 Javascript 模块,并且可以执行在任意 DOM 节点。Mangento 模块开发人员始终可以用自己系统来实现这种功能,但是 Magento 2 提供了一种标准的内置方法来实现它。
Data-mage-init 属性
除了
