当前位置: 技术文章>> magento2中的javascript初始化init方法

文章标题:magento2中的javascript初始化init方法
  • 文章分类: Magento
  • 19224 阅读
系统学习magento二次开发,推荐小册:《Magento中文全栈二次开发 》

本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。


Javascript 初始化方法

我们将要讨论的Magento javascript init方法解决了几个不同的问题。

首先,它们提供了一种标准机制来阻止将javascript直接嵌入到页面中。

其次,它们提供了一种调用独立 RequireJS 模块(定义为 )作为程序的方法。define

第三,它们提供了一种向该程序传递服务器端生成的JSON对象的方法。

第四,它们提供了一种方法来告诉该程序应该在哪些(如果有的话)DOM节点上运行。

牢记这四个目标。如果您正在努力解决这些自定义框架功能背后的心智模型,它们可能会为您提供帮助。

### 设置模块

我们将使用 pestle 通过运行以下三个命令来创建以单个 URL 端点命名的模块Pulsestorm_JavascriptInitTutorial

$ pestle.phar generate_module Pulsestorm JavascriptInitTutorial 0.0.1
$ pestle.phar generate_route Pulsestorm_JavascriptInitTutorial frontend pulsestorm_javascriptinittutorial
$ pestle.phar generate_view Pulsestorm_JavascriptInitTutorial frontend pulsestorm_javascriptinittutorial_index_index Main content.phtml 1column
$ php bin/magento module:enable Pulsestorm_JavascriptInitTutorial
$ php bin/magento setup:upgrade

任何通过Magento 2 for PHP MVC开发人员系列工作的人都应该熟悉这些命令。运行上述操作后,您应该能够在系统中访问以下URL

http://magento.example.com/pulsestorm_javascriptinittutorial/

并查看呈现的模板。app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

### 设置一个 RequireJS 模块

现在我们已经设置了一个Magento模块,让我们做一个快速回顾并创建一个RequireJS模块。首先,创建以下文件

//File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/web/example.js


define([], function(){
    alert("A simple RequireJS module");
    return {};    
});

这是一个非常简单的 RequireJS 模块。由于模块在文件系统上的位置,以及Magento加载javascript文件的方式,该模块的名称/标识符是Pulsestorm_JavascriptInitTutorial/example

接下来,更改 的内容,使其与以下内容匹配。content.phtml

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

<script type="text/javascript">
    requirejs(['Pulsestorm_JavascriptInitTutorial/example'],function(example){
        alert("Loaded");
        console.log(example);
    }); 
</script>

在这里,我们将创建一个具有单个模块依赖项的 RequireJS 程序。依赖项是我们刚刚创建的模块 ()。加载Pulsestorm_JavascriptInitTutorial/example

http://magento.example.com/pulsestorm_javascriptinittutorial/

系统中的 URL,您应该会看到警报。

如果以上任何内容对您来说是陌生的,您可能需要查看我们的Magento 2和RequireJS文章。

### X-Magento-Init

我们要讨论的第一个初始化技术是方法。此初始化方法的最基本版本允许您将 RequireJS 模块作为程序运行。更改模板的内容,使其与以下内容匹配<script type="text/x-magento-init">content.phtml

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

<div id="one" class="foo">
    Hello World
</div>
<div id="two" class="foo">
    Goodbye World
</div>    
<script type="text/x-magento-init">
    {
        "*": {
            "Pulsestorm_JavascriptInitTutorial/example":{}
        }
    }        
</script>

使用上述内容重新加载您的页面,您应该会看到我们文件中的声明。alertexample.js

如果您以前从未见过此语法,它看起来可能有点奇怪。让我们把它一块一块地拆开。

首先是标签<script/>

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

<script type="text/x-magento-init">
    //...
</script>

此标签不是 javascript 标签。请注意该属性。当浏览器无法识别脚本类型标记中的值时,它将忽略该标记的内容。Magento(类似于其他现代JavaScript框架)利用这种行为来发挥其优势。虽然这超出了本教程的范围,但正在运行Magento javascript代码,它将扫描脚本标签。如果您想自己探索这个问题,这个堆栈交换问题和答案是一个很好的起点。type="text/x-magento-init"text/x-magento-init

我们可以立即讨论的代码块的另一部分是以下对象x-magento-init

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

{
    "Pulsestorm_JavascriptInitTutorial/example":{}            
}

Magento将查看此对象的键,并将其(键)作为RequireJS模块包含在内。这就是加载脚本的内容。example.js

您可能想知道为什么这是一个没有值的对象。您可能还想知道为什么整个事物是另一个对象的一部分,带有 a 作为键。*

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

{
    "*": {/*...*/}
}

在我们讨论这个问题之前,我们需要谈谈javascript组件。

### Magento Javascript Components

上面的例子将我们的 RequireJS 模块作为一个程序运行。这是有效的,Magento本身经常使用该方法将RequireJS模块作为程序调用。然而,真正的力量是能够创建一个Magento Javascript组件。x-magento-initx-magento-init

Magento Javascript 组件是返回函数的 RequireJS 模块。Magento的系统代码将以特定的方式调用此函数,以公开额外的功能。

如果这没有意义,请尝试更改 RequireJS 模块,使其与以下内容匹配。

//File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/web/example.js


define([], function () {
    var mageJsComponent = function()
    {
        alert("A simple magento component.");
    };
    return mageJsComponent;
});

在这里,我们定义了一个函数并将其分配给一个名为 .然后,我们将其退回。mageJsComponent

如果您在上述情况下重新加载页面,您应该会在警告框中看到一个简单的 Magento 组件。

这可能看起来很愚蠢——如果Magento所做的只是调用它,那么返回一个函数有什么意义呢?你是对的,但那是因为我们遗漏了一些东西。尝试更改我们的模板,使其与以下内容匹配phtml

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

<div id="one" class="foo">
    Hello World
</div>
<div id="two" class="foo">
    Goodbye World
</div>    
<script type="text/x-magento-init">
    {
        "*": {
            "Pulsestorm_JavascriptInitTutorial/example":{"config":"value"}
        }
    }        
</script>

并更改我们的 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 组件时,Magento 调用返回的函数并包含来自 .text/x-magento-init

"Pulsestorm_JavascriptInitTutorial/example":{"config":"value"}        

这就是为什么 RequireJS 模块名称是一个键 — 这个对象的值是我们想要传递给组件的对象。

在这些示例中,这似乎是一个愚蠢的抽象。但是,在实际模块中,我们将使用 PHP 生成该 JSON。这个系统允许我们在模板中渲染JSON,然后将其传递给Javascript代码。这有助于避免直接使用 PHP 生成 Javascript 的问题,这可能导致代码非常混乱,并且很容易意外地滑入错误或安全问题。phtml

在我们结束之前,还有最后一个功能要讨论。你会记得我们说过x-magento-initx-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;
});

我们在这里所做的是向函数添加第二个参数。第二个参数将是我们希望程序运行的 DOM 节点。但是,如果您在上述情况下重新加载页面,您将在控制台中看到以下内容。mageJsComponent

> Object {config:"value"}

> false

Magento确实传递了一个值 - 但该值是。什么给?nodefalse

好吧,Magento无法神奇地知道我们要在哪些DOM节点上运行。我们需要告诉它!更改模板,使其与以下内容匹配。phtml

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

<div id="one" class="foo">Hello World</div>
<div id="two" class="foo">
    Goodbye World
</div>    
<script type="text/x-magento-init">
    {
        "#one": {
            "Pulsestorm_JavascriptInitTutorial/example":{"config":"value"}          
        }
    }        
</script>

在这里,我们已将 更改为 .我们之前使用的实际上是一个特例,用于不需要在 DOM 节点上运行的程序。这个对象的键实际上是一个CSS / jQuery样式选择器,它告诉Magento程序应该在哪些DOM节点上运行。如果我们在上述情况下重新加载页面,我们将在您的控制台中看到以下内容*#one*Pulsestorm_JavascriptInitTutorial/example

> Object {config: "value"}
> <div id="one" class="foo">Hello World</div>

您不仅限于 ID,还可以在此处使用 CSS 类标识符。将其更改为

#File: app/code/Pulsestorm/JavascriptInitTutorial/view/frontend/templates/content.phtml

".foo": {
    "Pulsestorm_JavascriptInitTutorial/example":{"config":"value"}          
}

您将在控制台中看到以下内容。

> Object {"config":"value"}
> <div id="one" class="foo">Hello World</div>
> Object {"config":"value"}
> <div id="two" class="foo">Goodbye World</div>

通过构建这种系统,Magento鼓励开发人员避免将他们的DOM节点硬编码到他们的RequireJS模块中。这意味着有一个系统级的路径来构建依赖于服务器端渲染的JSON的Javascript模块,并在任何任意DOM节点上运行。Magento模块开发人员总是有可能实现自己的系统来实现这种功能,但是Magento 2提供了一个标准,内置的方式来实现这一目标。x-magento-init

### 数据法师初始化属性

除了 之外,还有另一种方法可以在特定的 DOM 节点上调用类似的功能,那就是属性。尝试将现有模板替换为以下内容<script type="text/x-magento-init">data-mage-initphtml

<div data-mage-init='{"Pulsestorm_JavascriptInitTutorial/example": {"another":"example"}}'>A single div</div>

在上述操作到位的情况下重新加载页面,您应该会在 JavaScript 控制台中看到以下内容。

> Object {another: "example"}  
> <div>A single div</div>

在这里,我们向特定的 div 添加了一个属性。此属性的值是一个 JSON 对象。与类似,这个对象的键是我们想要作为程序或Magento Javascript组件调用的RequireJS模块,该值是一个嵌套的JSON对象,作为参数传递到我们的Magento Javascript组件函数中。data-mage-initx-magento-initconfig

<div data-mage-init='...'>A single div</div>

不幸的是,这是必需的。属性的值由严格的 JSON 解析器解析,这意味着 JSON 对象的引号必须是双引号——这意味着我们不能对属性使用双引号。虽然这在HTML5中技术上是可以的,但对于一定年龄的Web程序员来说,它带来了一些不好Microsoft首页记忆。data-mage-init

无论您最终在特定节点中使用组件还是属性,这两种技术都提供了一种标准的、系统统一的方式来将 Javascript 入口点引入您的页面。Magento的许多前端和后端UI功能都依赖于这种语法,因此即使您个人避开它们,了解这些系统的工作原理也是成为Magento 2开发人员的重要组成部分。<script type="text/x-magento-init">data-mage-init


推荐文章