文章列表


如何使用Magento 2将送货地址转换为HTML格式?

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>在今天的Magento 2指南中,我将解释如何使用Magento 2将送货地址转换为HTML格式?</p><p>电子商务企业的送货地址信息有助于成功将订单交付给客户。但是,在您的网站上以视觉上吸引人且有组织的格式呈现此地址可以增强用户体验并提高商店的整体专业性。</p><p>让我们学习如何使用 Magento 2 将送货地址转换为 HTML 格式。</p><p>使用Magento 2将送货地址转换为HTML格式的步骤:</p><p>步骤1:在“帮助程序”文件夹中创建一个数据.php文件。</p><p>app\code\Vendor\Extension\Helper</p><p>然后添加代码,如下所示。</p><pre class="brush:bash;toolbar:false">&lt;?php namespace&nbsp;Vendor\Extension\Helper; &nbsp; use&nbsp;Magento\Framework\App\Helper\AbstractHelper; &nbsp; class&nbsp;Data&nbsp;extends&nbsp;AbstractHelper { &nbsp;&nbsp;&nbsp;protected&nbsp;$orderRepository; &nbsp;&nbsp;&nbsp;protected&nbsp;$_addressConfig; &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;__construct( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\Magento\Sales\Api\OrderRepositoryInterface&nbsp;$orderRepository, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\Magento\Customer\Model\Address\Config&nbsp;$addressConfig &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) &nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;orderRepository&nbsp;=&nbsp;$orderRepository; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_addressConfig&nbsp;=&nbsp;$addressConfig; &nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;_getAddressHtml($orderId) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$order&nbsp;=&nbsp;$this-&gt;orderRepository-&gt;get($orderId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(NoSuchEntityException&nbsp;$e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;\Magento\Framework\Exception\LocalizedException(__(&#39;This&nbsp;order&nbsp;no&nbsp;longer&nbsp;exists.&#39;)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$address&nbsp;=&nbsp;$order-&gt;getShippingAddress(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$renderer&nbsp;=&nbsp;$this-&gt;_addressConfig-&gt;getFormatByCode(&#39;html&#39;)-&gt;getRenderer(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$renderer-&gt;renderArray($address); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>第2步: 现在,在 地址.php 在 块 文件夹。</p><p>app\code\Vendor\Extension\Block</p><p>然后添加代码,如下所示。</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp; namespace&nbsp;Vendor\Extension\Block; use&nbsp;Vendor\Extension\Helper\Data&nbsp;as&nbsp;Helper; &nbsp; class&nbsp;Address&nbsp;extends&nbsp;\Magento\Framework\View\Element\Template { &nbsp;&nbsp;&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;\Magento\Backend\Block\Template\Context&nbsp;$context &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;\Magento\Framework\Registry&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$registry &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;\Magento\Framework\Data\FormFactory&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$formFactory &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;array&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$helper; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;__construct( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\Magento\Backend\Block\Template\Context&nbsp;$context, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\Magento\Framework\Data\FormFactory&nbsp;$formFactory, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Helper&nbsp;$helper, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array&nbsp;$data&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent::__construct($context,&nbsp;$data); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;helper&nbsp;=&nbsp;$helper; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;getAddressHtml($orderId) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$this-&gt;helper-&gt;_getAddressHtml($orderId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>步骤3:然后,在布局文件夹中创建一个布局文件。</p><p>Vendor/Extension/view/frontend/layout/your_layout_file.xml</p><p>添加代码,如下所示。</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;?&gt; &lt;page&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:View/Layout/etc/page_configuration.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;referenceContainer&nbsp;name=&quot;content&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;block&nbsp;template=&quot;Vendor_Extension::template.phtml&quot;&nbsp;class=&quot;Vendor\Extension\Block\Address&quot;&nbsp;name=&quot;address.html&quot;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/referenceContainer&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt; &lt;/page&gt;</pre><p>步骤4:现在,在模板文件夹中创建一个t emplate.phtml文件</p><p>Vendor/Extension/view/frontend/templates/template.phtml</p><p>然后添加代码,如下所示。</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp;&nbsp;&nbsp;&nbsp;$orderId&nbsp;=&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;$shippingAddress&nbsp;=&nbsp;$block-&gt;getAddressHtml($orderId); &nbsp;&nbsp;&nbsp;&nbsp;$shippingFormat&nbsp;=&nbsp;strip_tags($shippingAddress); &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;$shippingFormat;&nbsp;&nbsp;&nbsp; ?&gt;</pre><p>结论:</p><p>通过执行以下步骤,您可以轻松修改送货地址显示以匹配商店的设计和品牌,从而提供更加精致和专业的在线购物体验。您还可以在Magento 2的订单网格中添加送货地址详细信息。</p><p><br/></p>

如何在Magento 2中使用JavaScript模块使用本地和cookie存储

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>今天,我将解释如何在Magento 2中使用JavaScript模块使用本地和cookie存储。</p><p>Cookie 是当用户通过网络浏览器浏览任何网站时存储在用户计算机中的一小段信息。之后,用户可以在需要时检索这些数据。Cookie 通常用于通过跟踪用户的操作来提供个性化的用户体验。</p><p>Magento 2提供了使用本地存储或cookie在浏览器中存储一些公共信息的功能。商店管理员可以使用 javascript 模块管理 cookie 信息。在商店前端显示cookie通知,以通过Magento 2的免费cookie合规性扩展获得用户的同意。</p><p>在Magento 2中使用JavaScript模块使用本地和cookie存储的步骤:</p><p>第 1 步:首先在扩展或主题中创建 JS 文件。为此,请创建自定义cookie.js</p><p>app\code\Vendor\Extension\view\Frontend\Web\Js\customcookie.js</p><p></p><pre class="brush:bash;toolbar:false">define([ &#39;jquery&#39;, &#39;uiComponent&#39;, &#39;jquery/jquery-storageapi&#39; ], function&nbsp;($,&nbsp;Component) { &nbsp;return&nbsp;Component.extend( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;defaults: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;cookieMessages:&nbsp;[] &nbsp;}, &nbsp;initialize:&nbsp;function&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._super(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.cookieMessages&nbsp;=&nbsp;$.cookieStorage.get(&#39;mage-string&#39;); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$.cookieStorage.set(&#39;mage-string&#39;,&nbsp;&#39;&#39;); &nbsp;} &nbsp;}); });</pre><p><span style="color: #6a9955;"></span><br/></p><p>要使用此功能,我们必须同时添加jquery和jquery/jquery-storageapi。</p><p>第 2 步:所以现在您可以使用</p><p>$.cookieStorage.get(<span style="color: #ce9178;">&#39;mage-string&#39;</span>)</p><p>步骤3:</p><p></p><pre class="brush:bash;toolbar:false">window.localStorage也支持将信息存储在本地存储中 window.localStorage.setItem(&#39;myname&#39;,&nbsp;&#39;Vendor&#39;); window.localStorage.getItem(&#39;myname&#39;); window.localStorage.removeItem(&#39;myname&#39;); window.localStorageclear();</pre><p><span style="color: #6a9955;"></span><br/></p><p>这些都是存储信息的不同方法。</p><p>结论:</p><p>因此,在上述代码的帮助下,所有人都能够做到。如果您遇到任何困难,请在下面的评论部分中提及,让我知道。进一步分享文章并保持更新。</p><p><br/></p>

如何在Magento 2中获取POST和GET请求

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>如何在Magento 2中获取POST和GET请求<br/></p><p>对于扩展Magento\Framework\App\Action\Action的控制器,可以在$this-&gt;getRequest()-&gt;getPost()的帮助下获取请求。</p><p>对于自定义类,请在构造函数中注入请求:</p><pre class="brush:bash;toolbar:false">&lt;?php&nbsp; namespace&nbsp;Namespace\Module\Something; class&nbsp;ClassName&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;$request; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;__construct( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\Magento\Framework\App\Request\Http&nbsp;$request,&nbsp;....//rest&nbsp;of&nbsp;parameters&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;request&nbsp;=&nbsp;$request; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...//rest&nbsp;of&nbsp;constructor&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;getPost()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$this-&gt;request-&gt;getPost();&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p><br/></p>

将自定义CSS / JS添加到Magento 2模块中

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>有几个选项可以将自定义CSS / JS添加到Magento 2模块中,以下选项是最简单的。</p><p>首先,您应该在模块文件夹中创建视图/&lt;区域&gt;/布局/默认.xml文件,例如,该文件可以是app/code/Df/Core。</p><p>不要忘记将&lt;区域&gt;替换为adminhtml或前端。</p><p>这是默认.xml的样子:</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;?&gt; &lt;page &nbsp;&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; &nbsp;&nbsp;&nbsp;layout=&quot;admin-1column&quot; &nbsp;&nbsp;&nbsp;xsi:noNamespaceSchemaLocation=&quot;../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd&quot; &gt; &nbsp;&nbsp;&nbsp;&lt;head&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;link&nbsp;src=&quot;Df_Core::core.js&quot;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;css&nbsp;src=&quot;Df_Core::core.css&quot;/&gt; &nbsp;&nbsp;&nbsp;&lt;/head&gt; &nbsp;&nbsp;&nbsp;&lt;body/&gt; &lt;/page&gt;</pre><p>将Df_Core替换为模块的名称,并将核心.js и 核心.css文件放入视图/&lt;区域&gt;/Web 文件夹。</p><p>此外,您可以对更少的文件执行相同的操作。创建 core.less 文件而不是 core.css并将其引用为 &lt;css <span style="color: #569cd6;">src</span>=“Df_Core::core.css”/&gt;更改上面的默认值.xml示例。因此,系统会将您的较少文件编译为 css。因此,您将能够在Magento 2模块中使用更少的文件!</p><p><br/></p>

如何在Magento 2导入期间自动生成订单自增ID

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>如果您需要将订单导入Magento 2怎么办?平台不支持此过程。但是,您可以在第三方订单导入解决方案的帮助下轻松添加缺少的功能。但是,如果您的导入文件不包含订单增量 ID,该怎么办?由于并非所有第三方模块都知道如何处理此问题,因此情况变得更加复杂。在下面的文章中,您将介绍如何在Magento 2导入期间自动生成订单增量ID。</p><p>缺少订单增量 ID</p><p>假设您需要从直销供应商处导入订单。这意味着您的订单导入文件中没有Magento订单增量或实体ID。但是,您需要在导入时自动生成这些ID,就像从Magento管理面板创建新订单时一样。让我们看看,如何做到这一点。</p><p>如何在Magento 2导入期间自动生成订单增量ID</p><p>您需要使用改进的导入和导出Magento 2扩展在Magento 2导入期间自动生成订单增量ID。首先,它可以从任何外部系统自动导入订单。此外,在以下两种情况下,该模块可以为订单自动生成增量 ID:</p><p>您的订单导入文件包含increment_id列,但它是空的<span style="color: #6a9955;">;</span></p><p>导入文件中缺少increment_id列。</p><p>在increment_id列为空的情况下,改进的导入和导出Magento 2扩展可以自动填充数据,将相应的记录添加到Magento数据库中。如果没有increment_id列,则根本不是问题。该模块可以从头开始创建它,为您填写必要的数据。</p><p>请按照以下步骤在Magento 2导入期间自动生成订单增量ID:</p><p>打开改进的导入和导出扩展<span style="color: #6a9955;">;</span></p><p>打开新的导入作业<span style="color: #6a9955;">;</span></p><p>选择订单作为您的导入实体<span style="color: #6a9955;">;</span></p><p>配置作业的设置<span style="color: #6a9955;">;</span></p><p>在“导入设置”部分,激活“对订单increment_id使用自动增量”特征。</p><p><img src="/uploads/images/20230825/349659d63c137bcf5bf859c7eae272ff.png" title="1.png" alt="" width="927" height="330"/></p><p>完成订单导入作业配置并保存。</p><p>除了能够在Magento 2导入期间自动生成订单增量ID之外,改进的导入和导出Magento 2扩展还允许您根据基于cron的计划,使用不同的文件格式(如CSV,XML,XLSX和JSON)和来源(Google Sheets,Dropbox,Google Drive等)导入和导出数据。您可以将映射应用于第三方数据,运行基于API的导入和导出,以及将任何实体移入和移出Magento 2网站。</p><p><br/><br/></p><p><br/></p>

如何将客户导入Magento 2并将其分配给客户组

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>很有可能,您知道需要将客户导入Magento 2的情况,但他们没有分配给客户组。在这种情况下,您需要手动重新分配它们。数据文件包含的元素越多,执行此数据输入例程所花费的时间就越多。但是,如果这个过程可以自动化呢?</p><p>下面,我们将说明如何将客户导入Magento 2并将他们分配给客户组,即使该客户组在您的电子商务网站上不存在。您所需要的只是改进的导入和导出。但是,在讨论解决方案之前,让我们更详细地探讨这个问题。</p><p>Magento 2 客户导入不会将客户分配到客户组</p><p>因此,如果您将客户导入Magento 2,并且他们未分配给您网站上存在的客户组,则您的group_id属性(此客户组的ID)可能为空。您可以仔细检查导入文件,应用必要的更改,然后重新导入。但是,这种方法不会节省您的时间。</p><p>在另一种情况下,您的Magento 2客户导入过程可能不会将客户分配到客户组,因为您的网站上不存在该客户组。在这种情况下,您需要在导入任何客户数据之前创建它,并在导入文件中指定组的 ID。</p><p>不幸的是,这两种情况都与大量手动数据输入有关。但是可以平滑边缘并自动将客户导入Magento 2。让我们看看如何。</p><p>如何将客户导入Magento 2并将其分配给客户组</p><p>正如我们上面提到的,您需要改进的导入和导出Magento 2扩展来解决此问题。此模块将三列添加到客户主文件:</p><p>_customer_group_code</p><p>_tax_class_name</p><p>_tax_class_id</p><p>此改进如何帮助将客户导入Magento 2并将其分配给客户组?我看看。</p><p>如果没有group_id属性或相应的列为空,则不再是问题。</p><p>如果您的网站上存在“_customer_group_code”列 中的客户组,则“改进的导入和导出”模块将获取_customer_group_code值并将客户添加到相应的客户组。</p><p>如果“_customer_group_code”列 中的客户组在您的网站上不存在,则该模块将采用_customer_group_code值和_tax_class_name值,并执行以下操作:</p><p>改进的“导入和导出”扩展程序 会动态创建一个新的客户组,如果_tax_class_name列中的税务规则名称来自“_customer_group_code”列 存在于您的网站上。</p><p>但是,如果您的网站上不存在与“_tax_class_name”列中的税务规则同名的税务规则,则不会创建新的客户组。发生这种情况是因为扩展不知道客户组与哪个税种相关。在这种情况下,它显示以下错误:X 行中的_tax_class_name不存在。这意味着您需要在Magento 2网站上创建相应的税收规则来解决此问题。</p><p>或者,改进的导入和导出扩展可以依赖于 _tax_class_id 属性。如果您的网站上存在具有导入表中 ID 的类,则会在导入过程中自动创建一个客户组,并将客户分配给该类。如果您网站上没有税级 ID 与客户导入文件中的税级 ID 匹配,则不会创建新的客户组。</p><p>请注意,_tax_class_id 属性的优先级高于 _tax_class_name 属性。但是,在您的Magento 2网站上至少有一个税收属性(_tax_class_id或_tax_class_name)就足以创建客户组并在导入过程中自动为其分配客户。</p><p>还值得一提的是,group_id属性的优先级高于_customer_group_code属性。如果它们的值不同,则改进的导入和导出扩展将从 group_id 属性中获取该值,以创建新的客户组,并在导入时为其分配客户。</p><p>我们希望这些信息能帮助您将客户导入Magento 2,并将他们比以往更快地分配给客户组!</p><p>除了能够将客户导入Magento 2并将他们分配给客户组(即使您的网站上不存在)之外,改进的导入和导出Magento 2扩展还允许您根据基于cron的时间表,使用不同的文件格式(例如CSV,XML,) XLSX和JSON)和来源(Dropbox,Google Drive等)。此外,可以将映射应用于第三方数据,以将信息从任何来源直接传输到您的电子商务网站。您还可以运行基于 API 的导入和导出流程,并使用 Google 表格将任何实体移入和移出您的 Magento 2 网站。</p><p><br/></p>

magento2中的Requirejs的初始化和使用方法详细介绍

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>今天,我们将重点介绍在Magento 2中构建的几乎所有JavaScript功能的基础库 - RequireJS。</p><p>在我们进入Magento的RequireJS实现之前,我们将对RequireJS的功能进行一次旋风式的浏览。</p><p><span style="color: #6a9955;">### RequireJS</span></p><p>RequireJS是一个javascript模块系统。它实现了JavaScript模块的异步模块定义(AMD)标准。在AMD的术语中,javascript模块提供了一种</p><p>运行不默认为全局命名空间的 JavaScript 程序</p><p>首先,下载 RequireJS 源代码并将其保存到名为 的文件夹中。scripts</p><p>然后,创建以下文件。</p><pre class="brush:bash;toolbar:false">&lt;!--&nbsp;File:&nbsp;require-example.html&nbsp;--&gt; &lt;!DOCTYPE&nbsp;html&gt; &lt;html&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;head&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;My&nbsp;Sample&nbsp;Project&lt;/title&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;data-main&nbsp;attribute&nbsp;tells&nbsp;require.js&nbsp;to&nbsp;load &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scripts/main.js&nbsp;after&nbsp;require.js&nbsp;loads.&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;script&nbsp;data-main=&quot;scripts/main&quot;&nbsp;src=&quot;scripts/require.js&quot;&gt;&lt;/script&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/head&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&gt;My&nbsp;Sample&nbsp;Project&lt;/h1&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt; &lt;/html&gt;</pre><p>如您所见,此页面在主 RequireJS 中加载,如下所示</p><pre class="brush:bash;toolbar:false">&lt;!--&nbsp;File:&nbsp;require-example.html&nbsp;--&gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script&nbsp;data-main=&quot;scripts/main&quot;&nbsp;src=&quot;scripts/require.js&quot;&gt;&lt;/script&gt;</pre><p>除了标准属性之外,还有自定义属性。这告诉 RequireJS 它应该使用模块作为程序的主入口点。在我们的例子中,它是 ,它对应于 中的文件。srcdata-mainscripts/mainscripts/mainscripts/main.js</p><p>创建以下文件。</p><p></p><pre class="brush:bash;toolbar:false">//File:&nbsp;scripts/main.js requirejs([],&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;Hello&nbsp;World&quot;); });</pre><p>创建上述内容后,在浏览器中加载您的 HTML 页面。您应该会看到警报。祝贺!您刚刚创建了第一个 RequireJS 程序。Hello World</p><p>就其本身而言,RequireJS并没有做很多jQuery的文档就绪函数无法完成的事情。</p><p></p><pre class="brush:bash;toolbar:false">jQuery(function(){ &nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;Hello&nbsp;World&quot;); });</pre><p>RequireJS的与众不同之处在于它的模块系统。例如,如果我们想使用一个名为 的假设模块,我们将更改我们的文件以匹配以下内容。helper/worldmain.js</p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;helper/world&#39;],&nbsp;function(helper_world)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;message&nbsp;=&nbsp;helper_world.getMessage(); &nbsp;&nbsp;&nbsp;&nbsp;alert(message); });</pre><p>也就是说,我们将要加载的模块指定为数组,并将该数组作为第一个参数传递给函数调用。然后,RequireJS 将模块导出的单个对象作为第一个参数传递给我们的主函数。requirejshelper/worldhelper_world</p><p></p><pre class="brush:bash;toolbar:false">//File:&nbsp;scripts/helper/world.js define([],&nbsp;function(){ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;o&nbsp;=&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp;o.getMessage&nbsp;=&nbsp;function() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&#39;Hello&nbsp;Module&nbsp;World&#39;; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;o; });</pre><p>模块定义与我们的主程序定义非常相似。主要区别在于使用函数而不是函数。的第一个参数是你想在模块中使用的 RequireJS 模块的列表(在我们的例子中,这是一个空数组——在现实世界中,大多数模块将使用其他模块)。第二个参数是 javascript 函数/闭包,它定义了模块将返回的内容。definerequirejsdefine</p><p><span style="color: #6a9955;">### 需要 JS 文件加载</span></p><p>默认情况下,RequireJS 会将模块名称转换为如下所示的路径helper/worldHTTP(S)</p><p>http://example.com/scripts/helper/world.js</p><p>https://example.com/scripts/helper/world.js</p><p>//example.com/helper/scripts/world.js</p><p>也就是说,模块名称转换为文件路径,最后一段是以 结尾的文件名。默认情况下,RequireJS 将使用脚本所在的文件夹作为其基础(在上面的示例中)。jsrequire.js/scripts</p><p>但是,RequireJS 允许您为脚本设置不同的基本路径。在启动 RequireJS 程序之前,请包含以下代码。</p><p></p><pre class="brush:bash;toolbar:false">require.config({ &nbsp;&nbsp;&nbsp;&nbsp;baseUrl:&nbsp;&#39;/my-javascript-code&#39;, });</pre><p>有了上述内容,当 RequireJS 需要加载模块时,它将从helper/world</p><p>http://example.com/my-javascript-code/helper/world.js</p><p>https://example.com/my-javascript-code/helper/world.js &nbsp; &nbsp;</p><p>//example.com/my-javascript-code/helper/world.js</p><p>此功能允许您将javascript文件存储在基于RequireJS的系统中的任何位置。</p><p><span style="color: #6a9955;">### RequireJS:模块命名</span></p><p>到目前为止,在我们的示例中,RequireJS 模块名称已绑定到该模块源在磁盘上的位置。换句话说,模块将始终位于 路径 .helper/worldhelper/world.js</p><p>RequireJS允许您通过配置来更改此设置。例如,如果您希望将模块命名为 ,则需要在程序启动前的某个地方运行以下配置代码helper/worldhello</p><p></p><pre class="brush:bash;toolbar:false">require.config({&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;paths:&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;hello&quot;:&nbsp;&quot;helper/world&quot; &nbsp;&nbsp;&nbsp;&nbsp;}, });</pre><p>配置键是我们可以重命名/别名模块的地方。对象的 是所需的名称 (),值是模块的实际名称 ()。pathskeypathshellohelper/world</p><p>完成上述配置后,以下程序</p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;hello&#39;],&nbsp;function(hello)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;Hello&nbsp;World&quot;); });</pre><p>将从路径加载模块。hellohelper/world.js</p><p><span style="color: #6a9955;">### Magento 2 和 RequireJS</span></p><p>这就把我们带到了Magento的RequireJS实现。Magento为您拉入了主要的RequireJS库,包括一些额外的配置,并提供了一种机制,可以让您添加自己的其他RequireJS配置。</p><p>你要注意的第一件事是Magento 2对RequireJS上述功能的使用。如果您查看Magento页面的源代码,您将看到如下所示的内容baseUrl</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;type=&quot;text/javascript&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;require.config( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&quot;baseUrl&quot;:&quot;http://magento.example.com/static/adminhtml/Magento/backend/en_US&quot;} &nbsp;&nbsp;&nbsp;&nbsp;); &lt;/script&gt;</pre><p>通过上述配置,这意味着当Magento 2遇到一个名为的RequireJS模块时,它将从如下所示的URL加载该模块源。helper/world</p><p>http://magento.example.com/static/adminhtml/Magento/backend/en_US/helper/world.js</p><p>如果您已经阅读了本系列的前几篇文章,您可能会将该 URL 识别为“从 Magento 模块加载前端静态资产”URL。这意味着您可以将 RequireJS 模块定义文件放在模块中</p><p>app/code/Package/Module/view/base/web/my_module.js</p><p>它将自动作为名为 RequireJS 模块提供</p><p>Package_Module/my_module</p><p>通过以下网址加载</p><p>http://magento.example.com/static/adminhtml/Magento/backend/en_US/Package_Module/my_module.js</p><p>这也意味着您可以使用如下所示的代码立即开始在模板中编写程序requirejsphtml</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;type=&quot;text/javascript&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;requirejs(&#39;Package_Module/my_module&#39;,&nbsp;function(my_module){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...program&nbsp;here... &nbsp;&nbsp;&nbsp;&nbsp;}); &lt;/script&gt;</pre><p>或者通过添加独立的 JavaScript 文件来执行相同的操作。</p><p><span style="color: #6a9955;">### 通过模块配置 RequireJS</span></p><p>在本教程的前面,我们介绍了两个 RequireJS 配置指令 — 和 .还有很多其他的RequireJS配置指令,当你进入框架的高级使用(或者你正在处理进入高级使用的Magento核心代码)时,你会发现你需要使用它们。baseUrlpath</p><p>每个Magento模块都能够通过名为.的特殊视图文件添加RequireJS配置指令。requirejs-config.js</p><pre class="brush:bash;toolbar:false">app/code/Package/Module/view/base/requirejs-config.js&nbsp;&nbsp;&nbsp;&nbsp; app/code/Package/Module/view/frontend/requirejs-config.js&nbsp;&nbsp;&nbsp;&nbsp; app/code/Package/Module/view/adminhtml/requirejs-config.js</pre><p>这是一个特殊的javascript文件,Magento将使用区域层次结构在每次页面加载时自动加载该文件。我们要试一试。首先,我们需要创建一个名为 .您可以使用以下命令使用 pestle 命令行框架创建基本模块文件Pulsestorm_RequireJsTutorial</p><pre class="brush:bash;toolbar:false">$&nbsp;pestle.phar&nbsp;generate_module&nbsp;Pulsestorm&nbsp;RequireJsTutorial&nbsp;0.0.1</pre><p>然后通过运行以下两个命令在 Magento 中启用该模块<br/></p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;module:enable&nbsp;Pulsestorm_RequireJsTutorial $&nbsp;php&nbsp;bin/magento&nbsp;setup:upgrade</pre><p>如果你有兴趣手动创建一个模块,或者好奇上面的 pestle 命令实际上在做什么,请查看我们的 Magento 2 简介 — 不再有 MVC 文章。</p><p>无论您如何创建它,一旦创建并启用了模块,请添加以下文件</p><p></p><pre class="brush:bash;toolbar:false">//File:&nbsp;app/code/Pulsestorm/RequireJsTutorial/view/base/requirejs-config.js alert(&quot;Hello&quot;);</pre><p>要了解RequireJS是如何做到这一点的,我们需要看看Magento实际在哪里提取这些文件。如果您查看Magento安装中的任何源页面,您应该会看到如下所示的标记requirejs-config.js</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;&nbsp;type=&quot;text/javascript&quot;&nbsp;&nbsp;src=&quot;http://magento.example.com/static/_requirejs/adminhtml/Magento/backend/en_US/requirejs-config.js&quot;&gt;&lt;/script&gt;</pre><p>如果您在浏览器中查看此文件的源代码,您将在如下所示的代码块中看到您的语句alert<br/></p><p></p><pre class="brush:bash;toolbar:false">(function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;Hello&nbsp;World&quot;); &nbsp;&nbsp;&nbsp;&nbsp;require.config(config); })();</pre><p>虽然这不是100%明显,但通过从Magento 2生成这个javascript代码块,我们可以向系统添加额外的RequireJS初始化。requirejs-config.js</p><p>用一个具体的例子来说,这可能更有意义。让我们用以下内容替换我们的requirejs-config.js</p><p></p><pre class="brush:bash;toolbar:false">var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;paths:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;my_module&quot;:&quot;Package_Module/my_module&quot; &nbsp;&nbsp;&nbsp;&nbsp;} }; alert(&quot;Done&quot;);</pre><p>我们在这里所做的是定义一个名为 的 JavaScript 变量,并更改了我们的值。如果你回去重新加载,现在可能会更清楚Magento在做什么。configalertrequirejs-config.js</p><p></p><pre class="brush:bash;toolbar:false">(function()&nbsp;{ var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;paths:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;my_module&quot;:&quot;Package_Module/my_module&quot; &nbsp;&nbsp;&nbsp;&nbsp;} }; alert(&quot;Done&quot;); require.config(config); })();</pre><p>对于每个人,Magento将创建一个看起来像这样的代码块requirejs-config.js</p><p></p><pre class="brush:bash;toolbar:false">(function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//CONTENTS&nbsp;HERE &nbsp;&nbsp;&nbsp;&nbsp;require.config(config); })();</pre><p>但替换为 的内容。//CONTENTS HERErequirejs-config.js</p><p></p><pre class="brush:bash;toolbar:false">var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;paths:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;my_module&quot;:&quot;Package_Module/my_module&quot; &nbsp;&nbsp;&nbsp;&nbsp;} }; alert(&quot;Done&quot;); require.config(config);</pre><p>这意味着如果我们在文件中定义一个变量,Magento 最终会将其传递给 .这将允许任何Magento模块开发人员使用RequireJS功能,如,,,或RequireJS配置指令中的许多其他功能之一。configrequirejs-config.jsrequire.configshimpathsbaseUrlmap</p><p><span style="color: #6a9955;">### 了解延迟加载</span></p><p>关于 RequireJS 的另一个重要事情是模块是延迟加载的。RequireJS不会加载任何javascript模块源文件,直到有人将该javascript模块作为依赖项使用。</p><p>换句话说,如果我们使用配置</p><p></p><pre class="brush:bash;toolbar:false">var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;paths:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;my_module&quot;:&quot;Package_Module/my_module&quot; &nbsp;&nbsp;&nbsp;&nbsp;} };</pre><p>默认情况下,Magento不会加载该文件。Magento只会在你将其用作模块后加载该文件。Package_Module/my_module.js</p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;my_module&#39;],&nbsp;function(my_module){ }); requirejs([&#39;Package_Module/my_module&#39;],&nbsp;function(my_module){ });&nbsp;&nbsp;&nbsp;&nbsp; define([&#39;Package_Module/my_module&#39;],&nbsp;function(my_module){ });</pre><p>请记住,RequireJS的要点是,日常的JavaScript开发人员不需要担心他们的程序如何对其源文件发出HTTP请求。延迟加载是一个实现细节,在理想情况下,它可以为最终用户节省下载特定页面可能不需要的源文件的带宽。</p><p>但是,在不太理想的情况下,这种延迟加载行为可能会使使用较旧的JavaScript框架和库变得棘手。当我们讨论一些jQuery陷阱时,我们将在下面讨论一个例子。</p><p><span style="color: #6a9955;">### 全局 jQuery 对象</span></p><p>即使你决定RequireJS不适合你,并且你想坚持在Magento 2中使用普通的jQuery,你仍然需要了解RequireJS如何与AMD标准之前的库进行交互。</p><p>在Magento 2中,jQuery作为RequireJS模块加载。这意味着如果您尝试使用如下所示的代码</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;type=&quot;text/javascript&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;jQuery(function(){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//your&nbsp;code&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;}); &lt;/script&gt;</pre><p>您的浏览器会抱怨未定义。这是因为在您将 jQuery 用作 RequireJS 模块之前,全局对象不会被初始化。如果您习惯于编写上述代码,则需要jQueryjQuery</p><p>将其替换为启动 RequireJS 程序执行的代码</p><p>将该程序配置为将模块用作依赖项jquery</p><p>换句话说,像这样的事情</p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;jquery&#39;],&nbsp;function(jQuery){ &nbsp;&nbsp;&nbsp;&nbsp;jQuery(function(){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//your&nbsp;code&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;}); });</pre><p>回顾一下 — 通过调用函数并向其传递模块依赖项列表以及将充当程序主入口点的匿名 JavaScript 函数来开始执行 RequireJS 程序。requirejs</p><p>模块依赖项列表是 的第一个参数 — 即以下代码说“我的程序依赖于模块”requirejsjquery</p><pre class="brush:bash;toolbar:false">requirejs([&#39;jquery&#39;],</pre><p>充当程序主入口点的匿名函数是函数的第二个参数requirejs<br/></p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;jquery&#39;],&nbsp;function(jQuery){ &nbsp;&nbsp;&nbsp;&nbsp;//... });</pre><p>RequireJS 将为您调用此函数。对于您配置的每个依赖项,RequireJS 将加载模块并传入其返回的(或者,在 RequireJS 中,导出)模块。</p><p>现代版本的jQuery将检测它们是否包含在RequireJS/AMD环境和返回全局对象的模块中。definejQuery</p><pre class="brush:bash;toolbar:false">if&nbsp;(&nbsp;typeof&nbsp;define&nbsp;===&nbsp;&quot;function&quot;&nbsp;&amp;&amp;&nbsp;define.amd&nbsp;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;define(&nbsp;&quot;jquery&quot;,&nbsp;[],&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;jQuery; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;); }</pre><p><span style="color: #6a9955;">### RequireJS 和 jQuery 插件</span></p><p>同时使用jQuery和RequireJS还有另一个问题。jQuery库比RequireJS和AMD标准早很多年,开发了自己的插件系统。虽然不是基于模块的,但这个系统在javascript的默认全局环境中玩得相对较好——插件开发人员通过修改单个全局jQuery对象来创建他们的插件。</p><p>这给 RequireJS 带来了一个问题——正如我们上面提到的,在程序中使用模块之前,直到 RequireJS 调用该程序的主入口函数,才会定义全局对象。这意味着包含jQuery插件的长期存在方式jQueryjqueryrequirejs</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;src=&quot;http://magento.example.com/js/path/to/jquery/plugin/jquery.cookie.js&quot;&gt;</pre><p>当插件尝试使用全局对象和/或别名时将失败。jQuery$<br/></p><p>//File: http://magento.example.com/js/path/to/jquery/plugin/jquery.cookie.js</p><p>var <span style="color: #569cd6;">config</span> = $.<span style="color: #569cd6;">cookie</span> = function (key, value, options) {</p><p>如果你想包含一个jQuery插件在Magento 2中使用,你需要通过RequireJS来完成。幸运的是,这个过程相对简单。</p><p>首先,您需要使用配置属性为插件路径创建别名。paths</p><p></p><pre class="brush:bash;toolbar:false">var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;paths:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;jquery.cookie&quot;:&quot;Package_Module/path/to/jquery.cookie.min&quot; &nbsp;&nbsp;&nbsp;&nbsp;} };</pre><p>上面的配置创建了一个名为的模块,该模块指向模块中的 jQuery cookie 插件源文件。jquery.cookiePackage_Module</p><p>在这一点上,你可能会认为通过做这样的事情来开始使用你的插件的jQuery是可以的</p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;jquery&#39;,&#39;jquery.cookie&#39;],&nbsp;function(jQuery,&nbsp;jQueryCookie){ &nbsp;&nbsp;&nbsp;&nbsp;//my&nbsp;code&nbsp;here });</pre><p>毕竟,将两者和依赖项列出应该会触发两个文件的加载。jqueryjquery.cookie</p><p>配置方面,这看起来像</p><p></p><pre class="brush:bash;toolbar:false">var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;paths:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;jquery.cookie&quot;:&quot;Package_Module/path/to/jquery.cookie.min&quot; &nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;shim:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;jquery.cookie&#39;:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;deps&#39;:[&#39;jquery&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} };</pre><p></p><p><br/></p>

magento2中的依赖注入原理以及使用方法介绍

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>许多流行的PHP框架实现了依赖注入系统——尽管说它们实现了自动依赖注入系统会更准确。在我们深入研究Magento的系统之前,我们要解释一下依赖注入要解决的问题。</p><p><span style="color: #6a9955;">### 了解依赖关系注入</span></p><p>理解依赖注入的最简单方法是通过示例。考虑以下PHP方法/伪代码</p><pre class="brush:bash;toolbar:false">//Obviously&nbsp;contrived&nbsp;--&nbsp;if&nbsp;only&nbsp;getting&nbsp;a&nbsp;price&nbsp;were&nbsp;this&nbsp;simple public&nbsp;function&nbsp;getFormattedPrice($sku) { &nbsp;&nbsp;&nbsp;&nbsp;$db&nbsp;&nbsp;=&nbsp;new&nbsp;DBHandler; &nbsp;&nbsp;&nbsp;&nbsp;$row&nbsp;=&nbsp;$db-&gt;query(&#39;SELECT&nbsp;price&nbsp;FROM&nbsp;products&nbsp;WHERE&nbsp;sku&nbsp;=&nbsp;?&#39;,&nbsp;$sku); &nbsp;&nbsp;&nbsp;&nbsp;$formatter&nbsp;=&nbsp;new&nbsp;PriceFormatter; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$formatter-&gt;asDollars($row[&#39;price&#39;]); }</pre><p>这是一个简化的示例,说明了获取产品价格的方法可能是什么样子的。从表面上看,这种方法没有错。它实例化数据库处理程序价格查询实例化格式化程序对象</p><p>使用格式化程序对象返回格式化价格</p><p>当其他人想要重用此方法时,问题就出现了。此方法现在依赖于特定类和特定类。即使你认为代码重用是一个不真实的行业神话,这两个依赖关系也使此方法更难在自动化框架中进行测试。您的测试框架现在依赖于与实际应用程序建立相同的数据库连接。DBHandlerPriceFormatter</p><p>此问题的解决方案是不要使用具有这些依赖项的方法。相反,您应该将依赖项注入到方法中。</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;getFormattedPrice($sku,&nbsp;$db,&nbsp;$formatter) { &nbsp;&nbsp;&nbsp;&nbsp;$row&nbsp;=&nbsp;$db-&gt;query(&#39;SELECT&nbsp;price&nbsp;FROM&nbsp;products&nbsp;WHERE&nbsp;sku&nbsp;=&nbsp;?&#39;,&nbsp;$sku); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$formatter-&gt;asDollars($row[&#39;price&#39;]); }</pre><p>重写后,此方法有两个新参数。这个想法是客户端程序员应该传入实例化的对象(即注入依赖项)。</p><p>这就是依赖注入的全部内容——维基百科条目有更多关于这个概念的例子,如果你能忍受 java 的例子,值得一读!</p><p><span style="color: #6a9955;">### 现代依赖注入</span></p><p>依赖注入是一个非常简单的概念,但如果你以前从未遇到过它,可能会有一些疑问在你的脑海中挠头。其中之一可能是这个</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;prepareDataForDisplay() { &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;$data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;new&nbsp;stdClass; &nbsp;&nbsp;&nbsp;&nbsp;$db&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;new&nbsp;DBHandler; &nbsp;&nbsp;&nbsp;&nbsp;$formatter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;new&nbsp;PriceFormatter; &nbsp;&nbsp;&nbsp;&nbsp;$data[&#39;price&#39;]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$this-&gt;getFormattedPrice($row[&#39;price&#39;]); &nbsp;&nbsp;&nbsp;&nbsp;//... } public&nbsp;function&nbsp;getFormattedPrice($sku,&nbsp;$db,&nbsp;$formatter) { &nbsp;&nbsp;&nbsp;&nbsp;$row&nbsp;=&nbsp;$db-&gt;query(&#39;SELECT&nbsp;price&nbsp;FROM&nbsp;products&nbsp;WHERE&nbsp;sku&nbsp;=&nbsp;?&#39;,&nbsp;$sku); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$formatter-&gt;asDollars($row[&#39;price&#39;]); }</pre><p>虽然我们已经替换了依赖项 - 我们真正所做的只是将它们转移到调用的方法(上面)的级别。因此,从概念上讲,依赖关系注入很简单,但是在哪里注入依赖关系以及在哪里实例化这些对象是悬而未决的。getFormattedPricegetFormattedPriceprepareDataForDisplay</p><p>这是许多PHP框架试图通过某种自动依赖注入来解决的问题。通过创建一个自动注入这些类型的依赖项的系统,框架消除了由谁以及如何注入依赖项的问题。如果这没有意义,请不要担心。在看了Magento的依赖注入的例子之后,它应该开始变得更有意义了。</p><p><span style="color: #6a9955;">### Magento 依赖注入</span></p><p>就像我们上次所做的那样,我们准备了一个包含一些示例代码的模块。该模块位于 GitHub 上,最简单的安装方法是手动下载最新版本。</p><p>如果您需要手动安装Magento扩展的帮助,我们之前的系列文章提供了完整的说明。</p><p>让我们通过运行以下命令来确保正确安装模块</p><p>$ php bin/magento ps:tutorial-object-manager-2</p><p>Hello Again World!</p><p>如果您看到“Hello Again World!”消息,您就可以开始了。</p><p>如果我们看一下实现命令的类,我们会看到以下内容。</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Command/Testbed.php protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$manager&nbsp;=&nbsp;$this-&gt;getObjectManager(); &nbsp;&nbsp;&nbsp;&nbsp;$helper&nbsp;=&nbsp;$this-&gt;getObjectManager()-&gt;create( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;\Pulsestorm\TutorialObjectManager2\Model\Example&#39;); &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$helper-&gt;sendHelloAgainMessage() &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre><p>我们在该方法中所做的只是实例化一个对象并调用其方法来获取一些输出文本。如果你看看这个类的构造函数executePulsestorm\TutorialObjectManager2\Model\ExamplesendHelloAgainMessagePulsestorm\TutorialObjectManager2\Model\Example</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Model/Example.php&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;function&nbsp;__construct() { &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;=&nbsp;new&nbsp;Message;&nbsp;// &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;messageObject&nbsp;=&nbsp;$object; }</pre><p>我们看到该类实例化一个对象并将其分配给该属性。我们使用短类名,因为此文件位于命名空间中。如果您需要一些帮助来开始使用 PHP 命名空间,我们的入门是一个不错的选择。Pulsestorm\TutorialObjectManager2\Model\MessagemessageObjectMessagePulsestorm\TutorialObjectManager2\Model</p><p>然后,在方法sendHelloAgainMessage</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Model/Example.php public&nbsp;function&nbsp;sendHelloAgainMessage() { &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$this-&gt;messageObject-&gt;getMessage(); }</pre><p>我们使用对象返回文本消息。Message</p><p>我们的(人为的)类对对象具有硬编码的依赖关系。以下是Magento 2如何解决这个问题。打开类定义文件,让我们将构造函数替换为以下代码Pulsestorm\TutorialObjectManager2\Model\ExamplePulsestorm\TutorialObjectManager2\Model\MessageExample.php</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Model/Example.php public&nbsp;function&nbsp;__construct(Message&nbsp;$message) { &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;messageObject&nbsp;=&nbsp;$message; }</pre><p>我们在这里所做的是向构造函数添加一个名为的参数,然后将该参数分配给属性。换句话说,我们已将硬编码依赖项替换为参数。这允许开发人员注入依赖项。您还会注意到我们在参数中包含了一个类型提示。$messagemessageObject</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Model/Example.php __construct(Message&nbsp;$message);</pre><p>此类型提示强制开发人员传入一个对象,该对象要么是对象,要么是其祖先链。同样,我们使用了短类名。以下内容本来是等效的,但要冗长得多。Pulsestorm\TutorialObjectManager2\Model\MessagePulsestorm\TutorialObjectManager2\Model\MessageMessage</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Model/Example.php __construct(\Pulsestorm\TutorialObjectManager2\Model\Message&nbsp;$message);</pre><p>如果您不熟悉类型提示,我们准备了有关它们的入门。</p><p>如果这是一个传统的PHP应用程序,我们会用如下所示的代码注入依赖项</p><p></p><pre class="brush:bash;toolbar:false">$dependency&nbsp;=&nbsp;new&nbsp;\Pulsestorm\TutorialObjectManager2\Model\Message; $helper&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;new&nbsp;\Pulsestorm\TutorialObjectManager2\Model\Example($dependency);</pre><p>但是,对于Magento 2的对象系统,我们无法提供参数。</p><pre class="brush:bash;toolbar:false">$helper&nbsp;=&nbsp;$this-&gt;getObjectManager()-&gt;create(&#39;Pulsestorm\TutorialObjectManager2\Model\Example&#39;);</pre><p>那么我们应该怎么做呢?<br/></p><p>这就是Magento 2的自动依赖注入系统的美妙之处。你不需要做任何事情。只需使用我们的新代码运行命令即可。</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-2 Hello&nbsp;Again&nbsp;World!</pre><p>相同的结果 — 即使我们没有做任何事情来传入参数。</p><p>这是自动依赖注入。在幕后,对象管理器将使用 PHP 的反射功能来查看类的类型提示/参数,自动为我们实例化对象,然后将其作为参数传递到构造函数中。__construct</p><p>第一次遇到它时,这似乎有点奇怪,但如果您不相信我们,只需向您的构造函数添加一些调试代码即可</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Model/Example.php&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;function&nbsp;__construct(Message&nbsp;$message) { &nbsp;&nbsp;&nbsp;&nbsp;var_dump(get_class($message)); &nbsp;&nbsp;&nbsp;&nbsp;exit; &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;messageObject&nbsp;=&nbsp;$message; }</pre><p>重新运行该命令,您将看到打印出的类名。</p><p></p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-2 string(47)&nbsp;&quot;Pulsestorm\TutorialObjectManager2\Model\Message&quot;</pre><p>一旦你克服了怪异,你可能会想知道为什么这更好。类型提示现在不就是硬编码依赖项吗?</p><p>不同之处在于对象管理器可以控制依赖项的实例化。作为模块开发人员,我们有很大的权力来改变对象管理器实例化注入的依赖项的方式。这是通过模块的文件(代表依赖注入)发生的。虽然Magento 2没有“类重写” - 它确实具有类似的,更强大的功能,所有这些都可以通过文件进行配置。在接下来的几篇文章中,我们将探讨所有这些选项,您将学习如何完全控制这些依赖项。etc/di.xmldidi.xml</p><p>这么长时间的对象管理器,我们几乎不认识你</p><p>在我们结束今天的比赛之前,还有最后一件事要做。如果你浏览Magento 2当前关于Magento 2对象系统的文档(通常标记为依赖注入),你会看到如下神秘的评论。</p><p>对象管理器必须仅在编写代码时存在,编写代码在引导过程的早期执行</p><p>此外,如果您一直密切关注Magento 2的开发,您就会知道曾经有一个静态工厂方法来抓取对象管理器实例,但该方法已被弃用并删除。</p><p>对象管理器类不适用于Magento 2中的日常使用。它(按照惯例)是为处理引导Magento的代码的系统级开发人员保留的。我们在这些教程中提供的方法是一个帮助程序,因此您可以了解对象管理器是什么。getObjectManager</p><p>如果您遵循Magento扩展开发的最佳实践,您将使用依赖注入来实例化几乎所有对象。起初这似乎是不可能的(我在2013年翻了个白眼),但随着Magento 2接近完成,越来越清楚这实际上是可能的。</p><p>我们将在以后的文章中介绍实现这一点的依赖关系注入功能。然而,这里有一些高层的保证,即“没有objet经理”并不像听起来那么疯狂。</p><p>Magento中的所有对象都使用对象管理器进行实例化 - 包括依赖项。换句话说,使用注入注入的对象本身可以具有具有自动注入依赖项的方法。__construct__construct</p><p>数据管理对象(我们过去称之为“ORM模型”)可以通过工厂对象实例化 - 这些工厂对象可以通过依赖注入注入。</p><p>如果它一直向下是依赖注入,您可能想知道堆栈顶部的内容。但请记住,所有有效的代码入口点(控制器操作方法、观察者对象/方法、块对象、Symfony 控制台命令等)都是通过配置创建的。这意味着Magento知道它们,当它需要实例化它们时,它使用对象管理器。这意味着所有这些对象都有注入__construct</p><p>尽管不建议这样做,并且可能会在未来的版本中消失,但到目前为止,有一种方法可以获取对象管理器的实例</p><p>关于最后一项?查看基类Pulsestorm\TutorialObjectManager2\Command\AbstractCommand</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Command/AbstractCommand.php use&nbsp;\Magento\Framework\ObjectManagerInterface; //... public&nbsp;function&nbsp;__construct(ObjectManagerInterface&nbsp;$manager) { &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;objectManager&nbsp;=&nbsp;$manager; &nbsp;&nbsp;&nbsp;&nbsp;parent::__construct(); } protected&nbsp;function&nbsp;getObjectManager() { &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$this-&gt;objectManager; }</pre><p>这是我们教程模块的 cli 类的基类,也是实现的位置。我们如何获得对象管理器的实例?当然,通过使用依赖注入!getObjectManager</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager2/Command/AbstractCommand.php&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;function&nbsp;__construct(ObjectManagerInterface&nbsp;$manager)</pre><p>这种模式可能需要一点时间来适应,并且可能看起来有点矫枉过正。但是,在企业环境中,一致性比本垒打更重要。沿着这条道路限制日常开发,并将更多的创造性工作留给深层次的系统开发人员,一个专注于敏捷的团队可以更好地完成最后期限并计算其速度。尽管它们很无聊和企业化,但这些设计模式是确保Magento 2稳步,无情地向发布迈进的重要组成部分。</p><p><br/></p>

magento2中的对象管理系统Object Manager

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>本文是解释Magento 2的对象管理器/依赖注入系统的系列文章中的第一篇。我们将探讨程序员(你!)如何在Magento 2中创建对象,探索Magento 2的对象系统带来的其他功能,在此过程中,我们将讨论Magento 1的变化,并开始探索Magento 2的约定。</p><p><span style="color: #6a9955;">### Magento 2命令行框架</span></p><p>Magento 2的架构转变带来的重大变化之一是命令行框架。这不是Magento 1中的简单框架(在我的短书No Frills Command Line Magento中讨论过)。相反,Magento 2附带了Symfony控制台组件的完整实现。</p><p>安装 Magento 2 后,您可以通过打开终端应用程序并键入以下命令来查看系统附带的默认命令列表。</p><p>$ php bin/magento</p><p>您应该看到如下所示的输出。</p><pre class="brush:bash;toolbar:false">Magento&nbsp;CLI&nbsp;version&nbsp;0.74.0-beta16 Usage: &nbsp;command&nbsp;[options]&nbsp;[arguments] Options: &nbsp;--help&nbsp;(-h)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Display&nbsp;this&nbsp;help&nbsp;message &nbsp;--quiet&nbsp;(-q)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do&nbsp;not&nbsp;output&nbsp;any&nbsp;message &nbsp;--verbose&nbsp;(-v|vv|vvv)&nbsp;Increase&nbsp;the&nbsp;verbosity&nbsp;of&nbsp;messages:&nbsp;1&nbsp;for&nbsp;normal &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output,&nbsp;2&nbsp;for&nbsp;more&nbsp;verbose&nbsp;output&nbsp;and&nbsp;3&nbsp;for&nbsp;debug &nbsp;--version&nbsp;(-V)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Display&nbsp;this&nbsp;application&nbsp;version &nbsp;--ansi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Force&nbsp;ANSI&nbsp;output &nbsp;--no-ansi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Disable&nbsp;ANSI&nbsp;output &nbsp;--no-interaction&nbsp;(-n)&nbsp;Do&nbsp;not&nbsp;ask&nbsp;any&nbsp;interactive&nbsp;question Available&nbsp;commands: &nbsp;help&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displays&nbsp;help&nbsp;for&nbsp;a&nbsp;command &nbsp;list&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lists&nbsp;commands &nbsp;//...&nbsp;full&nbsp;command&nbsp;list&nbsp;snipped&nbsp;...</pre><p>除了附带许多有用的命令外,第三方开发人员还可以创建Magento模块,向系统添加新命令。</p><p>在本教程中,我们将使用命令行框架来运行代码示例。命令行是一个很好的干净的地方,可以运行示例代码,观察输出,并且无需担心浏览器页面加载和Magento代码运行之间的抽象层和层。</p><p><span style="color: #6a9955;">### 安装教程示例代码</span></p><p>我们准备了一个Magento 2模块,其中包含一个简单的命令行界面(cli)命令。Magento 2模块安装的方法和原因仍在到位,所以现在我们最好的选择是手动安装这个模块。</p><p>我们已将模块源代码放在 GitHub 上。此模块将添加一个名为 的命令,我们将在下面使用它。安装此模块ps:tutorial-object-manager-1</p><p><span style="color: #6a9955;">### 导航到 GitHub 发布页面</span></p><p>找到最新版本(编写本教程时的 0.0.3 现在是 0.0.4),然后单击 或 链接下载版本存档ziptar.gz</p><p>将存档源提取到Magento 2安装中,与文件夹结构匹配app</p><p>您现在应该能够从Magento安装的根目录运行以下命令,并查看模块的顶级文件。lsPulsestorm_TutorialObjectManager1</p><pre class="brush:bash;toolbar:false">$&nbsp;ls&nbsp;-l&nbsp;app/code/Pulsestorm/TutorialObjectManager1/ total&nbsp;0 drwxr-xr-x@&nbsp;4&nbsp;alanstorm&nbsp;&nbsp;staff&nbsp;&nbsp;136&nbsp;Jul&nbsp;&nbsp;9&nbsp;08:49&nbsp;Command drwxr-xr-x@&nbsp;3&nbsp;alanstorm&nbsp;&nbsp;staff&nbsp;&nbsp;102&nbsp;Jul&nbsp;&nbsp;9&nbsp;08:49&nbsp;Model drwxr-xr-x@&nbsp;4&nbsp;alanstorm&nbsp;&nbsp;staff&nbsp;&nbsp;136&nbsp;Jul&nbsp;&nbsp;9&nbsp;08:49&nbsp;etc</pre><p>您还可以通过运行以下命令来检查模块是否已正确安装module:status</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;module:status List&nbsp;of&nbsp;enabled&nbsp;modules: Magento_Store //...</pre><p>如果已将模块正确解压缩到文件夹中,则在运行 时应看到类似于上述的输出。不过,眼尖的读者会注意到一个问题——虽然存在,但它被列为禁用模块。我们需要告诉Magento 2此模块已启用。app/codemodule:statusPulsestorm_TutorialObjectManager1</p><p>为此,我们需要编辑文件。在您喜欢的文本编辑器中打开此文件并查找以下部分app/etc/config.php</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/etc/config.php &lt;?php return&nbsp;array&nbsp;( &nbsp;&nbsp;&#39;modules&#39;&nbsp;=&gt; &nbsp;&nbsp;array&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Store&#39;&nbsp;=&gt;&nbsp;1, &nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;full&nbsp;module&nbsp;list&nbsp;snipped&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Wishlist&#39;&nbsp;=&gt;&nbsp;1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;), );</pre><p>该文件是一个简单的 PHP 包含文件,返回已配置模块的数组。您看到的模块是系统附带的核心模块。我们希望将模块添加到此列表的末尾。app/etc/config.php</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/etc/config.php &lt;?php return&nbsp;array&nbsp;( &nbsp;&nbsp;&#39;modules&#39;&nbsp;=&gt; &nbsp;&nbsp;array&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Store&#39;&nbsp;=&gt;&nbsp;1, &nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;full&nbsp;module&nbsp;list&nbsp;snipped&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Wishlist&#39;&nbsp;=&gt;&nbsp;1, &nbsp;&nbsp;&nbsp;&nbsp;&#39;Pulsestorm_TutorialObjectManager1&#39;&nbsp;=&gt;&nbsp;1 &nbsp;&nbsp;), );</pre><p>现在如果我们运行 ,我们应该看到我们的模块列在启用列表中。module:status</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;module:status List&nbsp;of&nbsp;enabled&nbsp;modules: Magento_Store //... Pulsestorm_TutorialObjectManager1 List&nbsp;of&nbsp;disabled&nbsp;modules: None</pre><p>与Magento 1相同,模块的全名来自其“命名空间”文件夹和“模块名称”文件夹的组合。但是,这里有一些事情可能会让Magento 1开发人员陷入循环。具体说来</p><p>Magento的模块命名空间现在代替了Magento_Mage_</p><p>和代码池消失了。所有模块都位于corecommunitylocalapp/code</p><p>核心团队已将“模块声明文件”替换为更简单的基于 PHP 的配置app/etc/modules</p><p>在我看来,要更改是中立的,但是删除代码池和模块声明文件对Magento来说是积极的。MagentoMage</p><p>虽然、、和代码池/包含文件夹允许系统所有者通过代码池覆盖对Magento功能进行快速更改,但这些文件在很大程度上导致了商家不愿意升级他们的系统,并且当开发人员更改过多的类文件的隐式契约时,通常会导致微妙的系统问题。corecommunitylocal</p><p>模块声明文件的丢失 - 虽然是一个有趣的想法(整个系统的一个全局配置)的一部分 - 不会被错过。虽然这些文件的初衷可能是配置哪些模块应该或不应该在系统中启用,但早期开发人员的布道和核心团队实践不佳意味着扩展开发人员开始将这些文件与他们的扩展打包在一起,并且任何希望这些文件是用户可配置的文件都消失了。简单的开/关配置阵列的Magento 2方法更有意义。app/etc/modules</p><p><span style="color: #6a9955;">### 运行命令和清除缓存</span></p><p>好的,现在我们已经安装了模块,我们要确保显示新命令。在我们这样做之前,还有一步要做。我们需要清除Magento的缓存。ps:tutorial-object-manager-1</p><p>从概念上讲,Magento 2中的缓存清除与Magento 1相同。有长时间运行的操作将运行一次,然后Magento缓存结果以便下次更快地加载。例如,虽然我们已经将新模块添加到Magento的配置中,但Magento的配置是缓存的,因此正在运行的系统实际上还不知道我们的模块。</p><p>Magento 2提供了一个用于清除缓存的cli命令。只需运行以下内容,您应该就可以开始了。</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;cache:clean Cleaned&nbsp;cache&nbsp;types: config layout block_html view_files_fallback view_files_preprocessing collections db_ddl eav full_page translate config_integration config_integration_api config_webservice</pre><p>我们说应该,因为尽管这将清除Magento的所有缓存类型,但这并不是100%清楚这是否会清除整个缓存。Magento 1包含许多非类型的缓存条目(例如Zend的模块列名称),Magento 1的缓存清除命令不会删除这些条目。Magento 2对于我们来说还太年轻,无法发现这些边缘情况,但是如果您不确定Magento的缓存是否被清除并且使用的是默认缓存存储,则可以通过手动删除Magento文件夹中的所有文件和文件夹来取消整个缓存。var/cache</p><p>$ rm -rf /path/to/magento/var/cache/*</p><p>此外,虽然它与我们在这里无关,但Magento 2也使用了一些自动代码生成功能,虽然不是严格的缓存,但如果某些系统配置或代码文件被更改/更新,则可能需要重新生成。如果要清除缓存,最好清除这些生成的代码文件。在开发计算机上执行此操作的最快和最简单的方法是删除</p><p>$ rm -rf /path/to/magento/var/generation/*</p><p>对于生产系统,您需要小心执行此操作。Magento 2仍然足够新,以至于代码生成的所有陷阱尚未被发现。</p><p>假设您已经清除了缓存,让我们寻找我们的命令。您可以使用命令查看命令列表list</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;list //... &nbsp;ps:tutorial-object-manager-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;cli&nbsp;playground&nbsp;for&nbsp;testing &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;commands //...</pre><p>假设您看到上面的命令,让我们尝试运行它!</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-1 You&nbsp;did&nbsp;it!</pre><p>祝贺!您只需手动安装第一个Magento模块。</p><p>更新:Kristof Ringleff指出,实际上有两个命令可以启用/禁用Magento 2模块(和)。在设置新模块时,您肯定希望使用这些命令module:enablemodule:disable</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;module:enable&nbsp;Pulsestorm_TutorialObjectManager1 -&nbsp;Pulsestorm_TutorialObjectManager1 To&nbsp;make&nbsp;sure&nbsp;that&nbsp;the&nbsp;enabled&nbsp;modules&nbsp;are&nbsp;properly&nbsp;registered,&nbsp;run &#39;setup:upgrade&#39;. Cache&nbsp;cleared&nbsp;successfully. Generated&nbsp;classes&nbsp;cleared&nbsp;successfully. Alert:&nbsp;Generated&nbsp;static&nbsp;view&nbsp;files&nbsp;were&nbsp;not&nbsp;cleared.&nbsp;You&nbsp;can&nbsp;clear&nbsp;them using&nbsp;the&nbsp;--clear-static-content&nbsp;option.&nbsp;Failure&nbsp;to&nbsp;clear&nbsp;static&nbsp;view&nbsp;files might&nbsp;cause&nbsp;display&nbsp;issues&nbsp;in&nbsp;the&nbsp;Admin&nbsp;and&nbsp;storefront.</pre><p>/ 命令的好处是他们会module:enablemodule:disable</p><p><span style="color: #6a9955;">### 自动为您清除缓存</span></p><p>自动为您删除生成的旧代码</p><p>通知您可能需要执行的其他操作</p><p>允许您启用/禁用模块,即使用于启用/禁用模块的内部方法发生变化</p><p>更改我们的命令</p><p>我们几乎准备好开始讨论对象管理器了。现在我们已经安装了示例模块,让我们尝试更改 的实现。ps:tutorial-object-manager-1</p><p>Magento 2中的每个cli命令都是用PHP类实现的。要更改命令的实现,您需要做的就是在您喜欢的文本编辑器中打开此类文件。尝试打开以下文件,并找到执行方法</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln(&quot;You&nbsp;did&nbsp;it!&quot;); }</pre><p>然后,编辑命令定义文件,使其如下所示</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln(&quot;Hello&nbsp;World!&quot;); }</pre><p>如果我们现在尝试运行该命令,我们应该看到以下输出。</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-1 Hello&nbsp;World!</pre><p>我们上面所做的只是将一条消息传递给命令行框架的方法——这是框架的等价物 or 。writelnechoprint</p><p>完成此操作后,我们终于可以开始讨论Magento的对象管理器了。</p><p>首先,让我们回顾一些 PHP 101。当您想在 PHP 中实例化对象时,请使用关键字。让我们在我们的方法中尝试一下newexecute</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;=&nbsp;new&nbsp;\Pulsestorm\TutorialObjectManager1\Model\Example; &nbsp;&nbsp;&nbsp;&nbsp;$message&nbsp;=&nbsp;$object-&gt;getHelloMessage(); &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$message &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre><p>尝试运行上面的代码,你应该看到这样的内容</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-1 Hello&nbsp;Magento!</pre><p>我们上面所做的只是</p><p>从类实例化对象Pulsestorm\TutorialObjectManager1\Model\Example</p><p>调用结果对象的方法以获取消息字符串,getHelloWorld</p><p>使用命令行框架的方法输出消息。writeln</p><p>到目前为止,这是普通的旧 PHP — 如果您不熟悉 PHP 命名空间或那些反斜杠字符,您可能会发现这个命名空间入门很有用。</p><p>没有什么能阻止你在Magento 2中使用普通的旧PHP类。但是,如果你想利用Magento 2的高级对象功能(自动构造函数依赖注入,对象代理等),你需要使用Magento的对象管理器。尝试以下代码</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$manager&nbsp;=&nbsp;$this-&gt;getObjectManager(); &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;); &nbsp;&nbsp;&nbsp;&nbsp;$message&nbsp;=&nbsp;$object-&gt;getHelloMessage(); &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$message &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre><p>运行上面的代码,你应该看到相同的输出</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-1 Hello&nbsp;Magento!</pre><p>这个新代码和我们的旧代码之间的最大区别在于这两行</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $manager&nbsp;=&nbsp;$this-&gt;getObjectManager(); $object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);</pre><p>第一个,,为我们获取对象管理器。这不是您在编写Magento 2扩展时通常会做的事情 - 这是我们为本教程添加的帮助程序方法。我们稍后会回到这个概念,但现在接受 将返回 Magento 对象管理器的实例。$<span style="color: #569cd6;">manager</span> = $this-&gt;getObjectManager()<span style="color: #6a9955;">;getObjectManagergetObjectManager</span></p><p>对象管理器是一个特殊的对象,Magento用它来实例化几乎所有的对象。这就是我们在第二行所做的</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; $object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);</pre><p>我们调用了对象管理器的方法,并以字符串形式传入 PHP 类名。在后台,对象管理器为我们实例化了一个。createPulsestorm\TutorialObjectManager1\Model\Example</p><p>最简单的形式就是Magento 2的对象管理器。这似乎是一个微不足道的差异,但是通过这个单一点路由所有对象实例化,Magento系统工程师能够赋予他们的对象许多“超能力”。</p><p>在我们讨论超能力之前,虽然完全介绍它超出了本文的范围,但Magento对象管理器的源代码在下面的类文件中。</p><pre class="brush:bash;toolbar:false">#File:&nbsp;lib/internal/Magento/Framework/ObjectManager/ObjectManager.php namespace&nbsp;Magento\Framework\ObjectManager; class&nbsp;ObjectManager&nbsp;implements&nbsp;\Magento\Framework\ObjectManagerInterface { &nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;&nbsp;&nbsp;&nbsp; }</pre><p>如果您是Magento 1开发人员,则对象管理器可以替代这三种方法。</p><p></p><pre class="brush:bash;toolbar:false">Mage::getModel(...); Mage::helper(...); Mage::getSingleton(&#39;core/layout&#39;)-&gt;createBlock(...);</pre><p>虽然Magento 2仍然具有模型,帮助程序和块的概念,但您不再需要知道这些对象的类别名(,等)。对象管理器可以实例化任何PHP类,而不仅仅是模型,帮助程序或块对象。core/templatemodel/product</p><p><span style="color: #6a9955;">### 自动单例对象</span></p><p>我们今天将通过讨论Magento的对象管理器赋予对象的超能力之一来结束 - 自动单例。不过,在我们这样做之前,我们可能应该描述一下我们所说的单例是什么意思!</p><p>尝试运行以下代码</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$manager&nbsp;=&nbsp;$this-&gt;getObjectManager(); &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;message&nbsp;=&nbsp;&#39;Hello&nbsp;PHP!&#39;; &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;getHelloMessage() &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;getHelloMessage() &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre><p>你应该看到这样的输出</p><pre class="brush:bash;toolbar:false">$&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-1 Hello&nbsp;PHP! Hello&nbsp;Magento!</pre><p>此代码类似于我们之前的示例,但增加了一些内容。首先,我们使用对象管理器从类中实例化一个对象。Pulsestorm\TutorialObjectManager1\Model\Example</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; $object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);</pre><p>然后我们为对象设置一个自定义消息字符串</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; $object-&gt;message&nbsp;=&nbsp;&#39;Hello&nbsp;PHP&#39;;</pre><p>然后我们使用 cli 框架的方法输出新消息。writeln</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; $output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;getHelloMessage() );</pre><p>这是第一段代码。在第二个代码块中</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; $object&nbsp;&nbsp;=&nbsp;$manager-&gt;create(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;getHelloMessage() );</pre><p>我们实例化了一个新对象,然后输出其默认消息。这意味着我们的程序输出Pulsestorm\TutorialObjectManager1\Model\Example</p><pre class="brush:bash;toolbar:false">Hello&nbsp;PHP! Hello&nbsp;Magento!</pre><p>是自定义消息,后跟默认消息。</p><p>非常简单的东西。</p><p>现在,让我们尝试完全相同的代码,只是我们将使用对象管理器的方法,而不是使用对象管理器的方法createget</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php&nbsp;&nbsp;&nbsp;&nbsp; protected&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output) { &nbsp;&nbsp;&nbsp;&nbsp;$manager&nbsp;=&nbsp;$this-&gt;getObjectManager(); &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;&nbsp;=&nbsp;$manager-&gt;get(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;message&nbsp;=&nbsp;&#39;Hello&nbsp;PHP!&#39;; &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;getHelloMessage() &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$object&nbsp;&nbsp;=&nbsp;$manager-&gt;get(&#39;Pulsestorm\TutorialObjectManager1\Model\Example&#39;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$object-&gt;getHelloMessage() &nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } Run&nbsp;this&nbsp;code,&nbsp;and&nbsp;your&nbsp;output&nbsp;will&nbsp;be&nbsp;a&nbsp;little&nbsp;different. $&nbsp;php&nbsp;bin/magento&nbsp;ps:tutorial-object-manager-1 Hello&nbsp;PHP Hello&nbsp;PHP</pre><p>我们的程序没有第二次打印默认消息,而是打印了我们在第一个对象上设置的相同自定义消息。为什么会这样?因为第二个对象是第一个对象。</p><p>这是Magento对象管理器的“自动单例”功能。如果您不熟悉这个概念,单例是一个只能实例化一次的对象。使用单例,将来实例化同一对象的尝试将返回原始实例。传统上,这是通过向类的构造函数添加特殊代码来实现的,但是使用Magento 2的对象管理器,任何类都可以转换为单例对象。</p><p>将返回上面的代码示例,第二次调用Magento时,我们返回了带有自定义消息集的原始对象。get</p><p>如果你来自Magento 1,/差异类似于createget</p><p></p><pre class="brush:bash;toolbar:false">Mage::getModel(...); Mage::getSingleton(...);</pre><p>差异。同样,这适用于Magento 2中的所有类和对象,而不仅仅是模型对象。</p><p>自动单例只是Magento 2的对象管理器赋予其对象的超能力之一。下次我们将讨论巨大的超能力 - 自动构造函数参数依赖注入 - 我们还将揭示为什么Magento的文档(看似矛盾)告诉你不要使用对象管理器。</p><p><br/></p>

magento2中整合knockoutjs的原理与使用方法

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>虽然KnockoutJS将自己标榜为MVVM(模型,视图,视图模型)框架,但PHP开发人员会发现模型部分有点薄。KnockoutJS本身没有数据存储的原生概念,并且像许多现代JavaScript框架一样,它被设计为与仅服务后端配合使用的最佳效果。即 KnockoutJS 的“模型”是其他一些框架,发出 AJAX 请求以填充视图模型值。</p><p>KnockoutJS可能会让你措手不及的另一件事是,它不是一个“全栈”的javascript应用程序框架(值得称赞的是,它不会这样标榜自己)。KnockoutJS对你如何把它包含在你的项目中,或者你如何组织你的代码没有意见(尽管文档清楚地表明KnockoutJS团队成员是RequireJS的粉丝)。</p><p>这给像Magento这样的服务器端PHP框架带来了一个有趣的挑战。不仅有一定程度的JavaScript脚手架需要围绕KnockoutJS,而且Magento 2不是一个纯服务的框架。虽然Magento 2的新API功能正在朝着这个方向大踏步前进,但Magento 2并不是一个纯服务的框架。即后端框架开发人员还需要构建脚手架以将业务对象数据放入 KnockoutJS。</p><p>今天我们将深入探讨Magento 2的KnockoutJS集成。在本教程结束时,您将了解Magento 2如何应用KnockoutJS绑定以及Magento 2如何初始化自己的自定义绑定。您还将了解Magento如何修改一些核心的KnockoutJS行为,为什么他们这样做,以及这些更改为您自己的应用程序和模块打开的其他可能性。</p><p>本文是介绍Magento 2中高级JavaScript概念的较长系列的一部分。虽然阅读之前的文章不是100%强制性的,但如果您在下面的概念上苦苦挣扎,您可能需要在下面的评论中指出您的Magento Stack Exchange问题之前查看以前的文章。</p><p><span style="color: #6a9955;">### 创建Magento模块</span></p><p>虽然这篇文章是javascript的重,但我们希望我们的示例代码在具有Magento基线HTML的页面上运行。这意味着添加一个新模块。我们将按照本系列第一篇文章中相同的方式执行此操作,并使用 pestle 创建一个具有 URL 端点的模块</p><pre class="brush:bash;toolbar:false">$&nbsp;pestle.phar&nbsp;generate_module&nbsp;Pulsestorm&nbsp;KnockoutTutorial&nbsp;0.0.1 $&nbsp;pestle.phar&nbsp;generate_route&nbsp;Pulsestorm_KnockoutTutorial&nbsp;frontend&nbsp;pulsestorm_knockouttutorial $&nbsp;pestle.phar&nbsp;generate_view&nbsp;Pulsestorm_KnockoutTutorial&nbsp;frontend&nbsp;pulsestorm_knockouttutorial_index_index&nbsp;Main&nbsp;content.phtml&nbsp;1column $&nbsp;php&nbsp;bin/magento&nbsp;module:enable&nbsp;Pulsestorm_KnockoutTutorial $&nbsp;php&nbsp;bin/magento&nbsp;setup:upgrade</pre><p>任何通过Magento 2 for PHP MVC开发人员系列工作的人都应该熟悉这些命令。运行上述操作后,您应该能够在系统中访问以下URL</p><p>http://magento.example.com/pulsestorm_knockouttutorial/</p><p>并查看呈现的模板。Pestle在这里不是强制性的 - 如果您有使用Magento页面的首选方式,请随意使用它。app/code/Pulsestorm/KnockoutTutorial/view/frontend/templates/content.phtml</p><p><span style="color: #6a9955;">### 需要JS初始化</span></p><p>在我们上一篇文章和官方的 KnockoutJS 教程中,KnockoutJS 初始化是一件简单的事情。</p><p><span style="color: #569cd6;"></span></p><pre class="brush:bash;toolbar:false">object&nbsp;=&nbsp;SomeViewModelConstructor(); ko.applyBindings(object);</pre><p>对于教程应用程序,这是有道理的。但是,如果您要将所有视图模型逻辑,自定义绑定,组件等保留在单个代码块中,则KnockoutJS将很快变得难以管理。</p><p>相反,Magento的核心团队创建了RequireJS模块,当它被列为依赖项时,将执行任何和所有KnockoutJS初始化。你可以像这样使用这个模块Magento_Ui/js/lib/ko/initialize</p><p></p><pre class="brush:bash;toolbar:false">requirejs([&#39;Magento_Ui/js/lib/ko/initialize&#39;],&nbsp;function(){ &nbsp;&nbsp;&nbsp;&nbsp;//your&nbsp;program&nbsp;here });</pre><p>关于这个 RequireJS 模块需要注意的一件有趣的事情是它不返回任何值。相反,将RequireJS模块列为依赖项的唯一目的是启动Magento的KnockoutJS集成。当您在野外看到它时,这可能会让您感到困惑。例如,考虑来自不同Magento RequireJS模块的这段代码。</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/core/app.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer/types&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer/layout&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Ui/js/lib/ko/initialize&#39; ],&nbsp;function&nbsp;(types,&nbsp;layout)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;function&nbsp;(data)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;types.set(data.types); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;layout(data.components); &nbsp;&nbsp;&nbsp;&nbsp;}; });</pre><p>声明了三个 RequireJS 依赖项,</p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/core/app.js [ &#39;./renderer/types&#39;, &#39;./renderer/layout&#39;, &#39;Magento_Ui/js/lib/ko/initialize&#39; ]</pre><p>但在生成的函数中仅使用两个参数</p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/core/app.js function&nbsp;(types,&nbsp;layout)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//... }</pre><p>我不清楚这是否是一种聪明的编程,或者它是否违反了 RequireJS 的精神。也许两者兼而有之。</p><p>无论如何,当你第一次在你自己的基于RequireJS的程序中使用这个库时,Magento将初始化KnockoutJS。后续包含实际上不会执行任何操作,因为 RequireJS 会在您第一次加载模块时缓存它们。</p><p><span style="color: #6a9955;">### KnockoutJS 初始化</span></p><p>如果我们看一下模块的来源Magento_Ui/js/lib/ko/initialize</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/initialize.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;ko&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./template/engine&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;knockoutjs/knockout-repeat&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;knockoutjs/knockout-fast-foreach&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;knockoutjs/knockout-es5&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/scope&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/staticChecked&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/datepicker&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/outer_click&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/keyboard&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/optgroup&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/fadeVisible&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/mage-init&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/after-render&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/i18n&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/collapsible&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/autoselect&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./extender/observable_array&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./extender/bound-nodes&#39; ],&nbsp;function&nbsp;(ko,&nbsp;templateEngine)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;ko.setTemplateEngine(templateEngine); &nbsp;&nbsp;&nbsp;&nbsp;ko.applyBindings(); });</pre><p>我们看到一个相对简单的程序,但它还包括其他十九个模块。介绍每个模块的功能超出了本文的范围。考虑以下精彩片段。</p><p>模块是模块的别名。koknockoutjs/knockout</p><p></p><pre class="brush:bash;toolbar:false">vendor/magento/module-theme/view/base/requirejs-config.js 11:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;ko&quot;:&nbsp;&quot;knockoutjs/knockout&quot;, 12:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;knockout&quot;:&nbsp;&quot;knockoutjs/knockout&quot;</pre><p>该模块是实际的挖空库文件。,和</p><p>模块是KnockoutJS社区的额外功能。这些都不是正式的 RequireJS 模块。knockoutjs/knockoutknockoutjs/knockout-repeatknockoutjs/knockout-fast-foreachknockoutjs/knockout-es5</p><p>以 开头的模块是 Magento 对 KnockoutJS 的自定义绑定。这些是正式的 RequireJS 模块,但实际上并不返回模块。相反,每个脚本操作全局对象以向 KnockoutJS 添加绑定。我们将在下面讨论绑定,但如果您是好奇的类型,请尝试调查其他绑定的实现细节。这是一个有用的练习。希望Magento尽快获得我们的官方文档。./bind/*koscope</p><p>这两个模块是KnockoutJS功能的Magento核心扩展。extender</p><p>该模块返回 KnockoutJS 模板引擎的自定义版本,是我们将深入研究的第一个自定义版本。./template/engine</p><p><span style="color: #6a9955;">### Magento KnockoutJS 模板</span></p><p>回顾一下,在股票 KnockoutJS 系统中,模板是预先编写的 DOM/KnockoutJS 代码块,您可以通过引用它们的 .这些块通过脚本标记添加到页面的 HTML 中,其类型idtext/html</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;type=&quot;text/html&quot;&nbsp;id=&quot;my_template&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&nbsp;data-bind=&quot;text:title&quot;&gt;&lt;/h1&gt; &lt;/script&gt;</pre><p>这是一个强大的功能,但给服务器端框架带来了一个问题——如何在页面上呈现正确的模板?您如何确定模板将在那里而不每次都重新创建它?KnockoutJS的解决方案是将组件绑定与RequireJS等库一起使用,但这意味着您的模板绑定到特定的视图模型对象。</p><p>Magento的核心工程师需要一种更好的方法来加载KnockoutJS模板 - 他们通过将本机KnockoutJS模板引擎替换为从RequireJS模块加载的引擎来实现这一点。Magento_Ui/js/lib/ko/template/engine</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/initialize.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;ko&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./template/engine&#39;, &nbsp;&nbsp;&nbsp;&nbsp;//... ],&nbsp;function&nbsp;(ko,&nbsp;templateEngine)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;ko.setTemplateEngine(templateEngine); &nbsp;&nbsp;&nbsp;&nbsp;//... });</pre><p>如果我们看一下 RequireJS 模块Magento_Ui/js/lib/ko/template/engine</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/template/engine.js /** &nbsp;*&nbsp;Copyright&nbsp;©&nbsp;2016&nbsp;Magento.&nbsp;All&nbsp;rights&nbsp;reserved. &nbsp;*&nbsp;See&nbsp;COPYING.txt&nbsp;for&nbsp;license&nbsp;details. &nbsp;*/ define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;ko&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./observable_source&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer&#39; ],&nbsp;function&nbsp;(ko,&nbsp;Source,&nbsp;Renderer)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;RemoteTemplateEngine, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeTemplateEngine&nbsp;=&nbsp;ko.nativeTemplateEngine, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sources&nbsp;=&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;RemoteTemplateEngine.prototype&nbsp;=&nbsp;new&nbsp;NativeTemplateEngine; &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;RemoteTemplateEngine.prototype.makeTemplateSource&nbsp;=&nbsp;function&nbsp;(template) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;RemoteTemplateEngine; });</pre><p>我们看到Magento制作了一个新对象,该对象原型继承自本机KnockoutJS渲染引擎,然后修改了一些方法来添加自定义行为。如果你不了解你的javascript内部,这意味着Magento复制了股票KnockoutJS模板系统,对其进行了一些更改,然后将其新模板引擎换成库存模板引擎。</p><p>这些修改的实现细节超出了本文的范围,但最终结果是一个 KnockoutJS 引擎,它可以通过 Magento 模块的 URL 加载模板。</p><p>如果这没有意义,一个例子应该澄清问题。将以下内容添加到我们的文件中。content.phtml</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/KnockoutTutorial/view/frontend/templates/content.phtml&nbsp;&nbsp;&nbsp;&nbsp; &lt;div&nbsp;data-bind=&quot;template:&#39;Pulsestorm_KnockoutTutorial/hello&#39;&quot;&gt;&lt;/div&gt;</pre><p>在这里,我们添加了一个 KnockoutJS 绑定并传递给它字符串。如果我们在上述情况下重新加载页面,您将在 javascript 控制台中看到如下错误templatePulsestorm_KnockoutTutorial/hello</p><p>&gt; GET http://magento-2-0-4.dev/static/frontend/Magento/luma/en\_US/Pulsestorm\_KnockoutTutorial/template/hello.html 404 (Not Found)</p><p>Magento采用了我们的字符串()并使用第一部分()来创建视图资源的基本URL,并使用第二部分()和附加的前缀来完成URL。如果我们向以下文件添加 KnockoutJS 视图Pulsestorm_KnockoutTutorial/helloPulsestorm_KnockoutTutorialhellotemplate.html</p><pre class="brush:bash;toolbar:false">#File:&nbsp;app/code/Pulsestorm/KnockoutTutorial/view/frontend/web/template/hello.html &lt;p&nbsp;data-bind=&quot;style:{fontSize:&#39;24px&#39;}&quot;&gt;Hello&nbsp;World&lt;/p&gt;</pre><p>并重新加载页面,我们将看到Magento从上面的URL加载了我们的模板,并应用了其KnockoutJS绑定。</p><p>此功能使我们能够避免在需要新模板时用标签乱扔 HTML 页面,并鼓励在 UI 和 UX 功能之间重用模板。&lt;script <span style="color: #569cd6;">type</span>=<span style="color: #ce9178;">&quot;text/html&quot;</span>&gt;</p><p><span style="color: #6a9955;">### 无视图模型</span></p><p>回到模块,在Magento设置自定义模板引擎之后,Magento调用KnockoutJS的方法。这将启动将当前 HTML 页面呈现为视图。如果我们看一下该代码,就会立即弹出一些内容。initialize.jsapplyBindings</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/initialize.js ko.setTemplateEngine(templateEngine); ko.applyBindings();</pre><p>Magento在没有视图模型的情况下调用。虽然这是一个合法的 KnockoutJS 调用——告诉 KnockoutJS 在没有数据或视图模型逻辑的情况下应用绑定似乎毫无用处。没有数据的视图有什么用?applyBindings</p><p>在股票KnockoutJS系统中,这将是毫无用处的。理解Magento在这里做什么的关键是在我们的KnockoutJS初始化中备份</p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/initialize.js define([ &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bind/scope&#39;, &nbsp;&nbsp;&nbsp;&nbsp;//... ],</pre><p>Magento的KnockoutJS团队创建了一个名为的自定义KnockoutJS绑定。下面是一个使用范围的示例 - 从Magento 2主页提升。scope</p><pre class="brush:bash;toolbar:false">&lt;li&nbsp;class=&quot;greet&nbsp;welcome&quot;&nbsp;data-bind=&quot;scope:&nbsp;&#39;customer&#39;&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;span&nbsp;data-bind=&quot;text:&nbsp;customer().fullname&nbsp;?&nbsp;$t(&#39;Welcome,&nbsp;%1!&#39;).replace(&#39;%1&#39;,&nbsp;customer().fullname)&nbsp;:&nbsp;&#39;Default&nbsp;welcome&nbsp;msg!&#39;&quot;&gt;&lt;/span&gt; &lt;/li&gt;</pre><p>当你像这样调用 scope 元素时</p><p><span style="color: #569cd6;">data-bind</span>=<span style="color: #ce9178;">&quot;scope: &#39;customer&#39;&quot;</span></p><p>Magento将客户视图模型应用于此标签及其后代。</p><p>您可能想知道 - 客户视图模型到底是什么?!如果您在主页的源代码中再往下看一点,您应该会看到以下脚本标记</p><pre class="brush:bash;toolbar:false">&lt;script&nbsp;type=&quot;text/x-magento-init&quot;&gt; { &nbsp;&nbsp;&nbsp;&nbsp;&quot;*&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Magento_Ui/js/core/app&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;components&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;customer&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;component&quot;:&nbsp;&quot;Magento_Customer/js/view/customer&quot; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} } &lt;/script&gt;</pre><p>正如我们从本系列的第一篇文章中知道的那样,当Magento遇到带有属性的脚本标签时,它将text/x-magento-init*</p><p>初始化指定的 RequireJS 模块 (Magento_Ui/js/core/app)</p><p>调用该模块返回的函数,传入数据对象</p><p>RequireJS 模块是一个实例化 KnockoutJS 视图模型以与属性一起使用的模块。它的完整实现超出了本文的“范围”,但在高层次上,Magento将为每个配置为的RequireJS模块实例化一个新的javascript对象,并且该新对象成为视图模型。Magento_Ui/js/core/appscopecomponent</p><p>如果这没有意义,让我们通过上面的示例。Magento查看密钥,并看到一个密钥/对象对。x-magento-initcomponents</p><pre class="brush:bash;toolbar:false">&quot;customer&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&quot;component&quot;:&nbsp;&quot;Magento_Customer/js/view/customer&quot; }</pre><p>因此,对于密钥,Magento将运行等效于以下内容的代码。customer</p><p></p><pre class="brush:bash;toolbar:false">//gross&nbsp;over&nbsp;simplification var&nbsp;ViewModelConstructor&nbsp;=&nbsp;requirejs(&#39;Magento_Customer/js/view/customer&#39;); var&nbsp;viewModel&nbsp;=&nbsp;new&nbsp;ViewModelConstructor; viewModelRegistry.save(&#39;customer&#39;,&nbsp;viewModel);</pre><p>如果特定组件对象中有额外的数据</p><pre class="brush:bash;toolbar:false">&quot;customer&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&quot;component&quot;:&nbsp;&quot;Magento_Customer/js/view/customer&quot;, &nbsp;&nbsp;&nbsp;&nbsp;&quot;extra_data&quot;:&quot;something&quot; }</pre><p>Magento也会将该数据添加到视图模型中。</p><p>完成上述操作后,视图模型注册表将具有一个名为 的视图模型。这是Magento将应用于绑定的视图模型。<span style="color: #569cd6;">customerdata-bind</span>=<span style="color: #ce9178;">&quot;scope: &#39;customer&#39;&quot;</span></p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/bind/scope.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;ko&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;uiRegistry&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;jquery&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;mage/translate&#39; ],&nbsp;function&nbsp;(ko,&nbsp;registry,&nbsp;$)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update:&nbsp;function&nbsp;(el,&nbsp;valueAccessor,&nbsp;allBindings,&nbsp;viewModel,&nbsp;bindingContext)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;component&nbsp;=&nbsp;valueAccessor(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;apply&nbsp;=&nbsp;applyComponents.bind(this,&nbsp;el,&nbsp;bindingContext); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(typeof&nbsp;component&nbsp;===&nbsp;&#39;string&#39;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;registry.get(component,&nbsp;apply); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;(typeof&nbsp;component&nbsp;===&nbsp;&#39;function&#39;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;component(apply); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//... });</pre><p>它是从视图模型注册表中获取命名视图模型的行,然后以下代码实际上是在 KnockoutJS 中将对象作为视图模型应用的代码registry.get(component, apply)<span style="color: #6a9955;">;</span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/ko/bind/scope.js //the&nbsp;component&nbsp;variable&nbsp;is&nbsp;our&nbsp;viewModel function&nbsp;applyComponents(el,&nbsp;bindingContext,&nbsp;component)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;component&nbsp;=&nbsp;bindingContext.createChildContext(component); &nbsp;&nbsp;&nbsp;&nbsp;ko.utils.extend(component,&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$t:&nbsp;i18n &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;ko.utils.arrayForEach(el.childNodes,&nbsp;ko.cleanNode); &nbsp;&nbsp;&nbsp;&nbsp;ko.applyBindingsToDescendants(component,&nbsp;el); }</pre><p>该变量来自模块,该模块是 RequireJS 模块的别名。registryuiRegistryMagento_Ui/js/lib/registry/registry</p><pre class="brush:bash;toolbar:false">vendor/magento/module-ui/view/base/requirejs-config.js 17:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uiRegistry:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Ui/js/lib/registry/registry&#39;,</pre><p>如果很多东西飞过你的头,别担心。如果要查看特定范围的绑定中可用的数据,以下调试代码应指导您。</p><pre class="brush:bash;toolbar:false">&lt;li&nbsp;class=&quot;greet&nbsp;welcome&quot;&nbsp;data-bind=&quot;scope:&nbsp;&#39;customer&#39;&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;pre&nbsp;data-bind=&quot;text:&nbsp;ko.toJSON($data,&nbsp;null,&nbsp;2)&quot;&gt;&lt;/pre&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;...&nbsp;--&gt; &lt;/li&gt;</pre><p>如果您是有兴趣深入了解创建视图模型的真实代码(而不是我们上面的简化伪代码)的人之一,则可以从该模块开始。Magento_Ui/js/core/app</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/core/app.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer/types&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer/layout&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;Magento_Ui/js/lib/ko/initialize&#39; ],&nbsp;function&nbsp;(types,&nbsp;layout)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;function&nbsp;(data)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;types.set(data.types); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;layout(data.components); &nbsp;&nbsp;&nbsp;&nbsp;}; });</pre><p>此模块具有名为 的依赖项。正是在这个依赖模块中,Magento初始化视图模型,并将它们添加到视图模型注册表中。Magento_Ui/js/core/renderer/layout</p><p><span style="color: #6a9955;">#File: vendor/magento/module-ui/view/base/web/js/core/renderer/layout.js</span></p><p>代码在那里有点粗糙,但如果你需要知道这些视图模型是如何实例化的,那就是你可以找到它们的地方。</p><p><span style="color: #6a9955;">### 具有任何其他名称的组件</span></p><p>所有这一切中的一个粘性检票口是单词组件。这个绑定+系统基本上是对原生KnockoutJS组件系统的不同看法。scopex-magento-init</p><p>通过使用与KnockoutJS相同的组件术语,Magento开辟了一个混乱的新世界。甚至官方文档似乎对组件是什么或不是什么有点困惑。这就是一个大型软件团队的生活,左手不知道右手在做什么——身体的其他部分对第三只手从背部长出来感到害怕。</p><p>当与同事讨论这些功能或在Magento论坛上提问时,区分KnockoutJS组件和Magento组件非常重要。</p><p><span style="color: #6a9955;">### 2.1 候选版本中的更改</span></p><p>为了结束今天的比赛,我们将讨论Magento 2.1候选版本中对上述内容的一些更改。从概念上讲,系统仍然相同,但细节有一些变化。</p><p>首先,KnockoutJS的初始化现在发生在RequireJS模块中。Magento_Ui/js/lib/knockout/bootstrap</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/lib/knockout/bootstrap.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;ko&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./template/engine&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;knockoutjs/knockout-es5&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./bindings/bootstrap&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./extender/observable_array&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./extender/bound-nodes&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;domReady!&#39; ],&nbsp;function&nbsp;(ko,&nbsp;templateEngine)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;ko.uid&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;ko.setTemplateEngine(templateEngine); &nbsp;&nbsp;&nbsp;&nbsp;ko.applyBindings(); });</pre><p>请注意,Magento的核心开发人员将所有绑定加载移动到一个单独的模块,定义在Magento_Ui/js/lib/knockout/bindings/bootstrap</p><p><span style="color: #6a9955;">#File: vendor/magento/module-ui/view/base/web/js/lib/knockout/bindings/bootstrap.js</span></p><p>最后,返回的“Magento Javascript组件”有一个包含参数的更改方法签名,并且函数的参数清楚地表明它的签名也发生了变化。Magento_Ui/js/core/appmergelayoutlayout</p><p><span style="color: #6a9955;"></span></p><pre class="brush:bash;toolbar:false">#File:&nbsp;vendor/magento/module-ui/view/base/web/js/core/app.js define([ &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer/types&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;./renderer/layout&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&#39;../lib/knockout/bootstrap&#39; ],&nbsp;function&nbsp;(types,&nbsp;layout)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&#39;use&nbsp;strict&#39;; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;function&nbsp;(data,&nbsp;merge)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;types.set(data.types); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;layout(data.components,&nbsp;undefined,&nbsp;true,&nbsp;merge); &nbsp;&nbsp;&nbsp;&nbsp;}; });</pre><p>除了对实现细节感兴趣的人感兴趣之外,这些变化还指出了Magento的javascript模块和框架正在迅速变化的事实,与PHP代码不同,Magento的RequireJS模块没有标记来表示稳定性。@api</p><p>除非你绝对需要,否则最好避免动态更改这些核心模块的行为,并尽可能保持你自己的JavaScript独立。</p><p><br/></p>