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。後端