magento2 front-end大量运用了KnockoutJS,大量的数据能即时更新而且不须要刷新页面,数据无疑是经过AJAX方式获取,但为了效率,AJAX下载后数据会保存到Storage,只有被通知数据过时时才会再次从AJAX更新数据。所以并不能仅仅使用传统的AJAX,须要把流程封装起来。magento2的确提供了一套方法,无奈并无文档说明,只能本身研究。javascript
magento2把AJAX数据分类打包,分红若干个section,而每一个section对应一个能获取数据的PHP类。因此第一步应该声明一个section与定义一个类。php
用di.xml声明section并指定PHP类前端
<!-- Vendor/Samples/etc/frontend/di.xml --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Customer\CustomerData\SectionPoolInterface"> <arguments> <argument name="sectionSourceMap" xsi:type="array"> <item name="book" xsi:type="string">Vendor\Samples\CustomerData\Book</item> </argument> </arguments> </type> </config>
建立PHP类,必须定义getSectionData并返回array数据,它会以JSON格式提交到前端java
// Vendor/Samples/CustomerData/Book.php namespace Vendor\Samples\CustomerData; use Magento\Customer\CustomerData\SectionSourceInterface; class Book extends \Magento\Framework\DataObject implements SectionSourceInterface { /** * {@inheritdoc} */ public function getSectionData() { return [ 'message' => 'hello world' ]; } }
完成以上两步并清除缓存,就能够在前端任意UI组件中调用ajax
require( [ 'ko', uiComponent, 'Magento_Customer/js/customer-data' ], function( ko , Component, customerData ) { return Component.extend({ initialize: function () { // 获取数据是observable var book = customerData.get('book'); // 建立名为message的observable,当customerData被更新(如ajax返回),会被同步到message this.message = ko.computed(function(){ // 有data_id意味着数据已准备好 if(book().data_id != undefined) return book().message; else { // reload即立刻提取远程数据,更新本地缓存。在完成提取以前可先返回空值 customerData.reload(['book']); return ''; } }, this); // 使名叫book的section失效,在下次刷新页面时会自动reload // customerData.invalidate(['book']); } }); } );
customer-data不会一直向后端提取数据,它会把数据放在Local Storage,若是Section更名,请求可能会一直出错,这是由于请求数据也放在Local Storage里,须要清空Local Storage才能获得更新,例如Local Storage的mage-cache-storage-section-invalidation。后端