Magento 2 визуализирует карты Google при оформлении заказа
Я расширил страницу оформления заказа magento 2. Добавлены методы доставки и пользовательские поля для метода доставки.
Переключатели - это список местоположений. Мне нужно добавить карту для этих мест. Список местоположений был добавлен в способ доставки с помощью атрибутов расширения в плагине.
$extensionAttribute = ($result->getExtensionAttributes())
? $result->getExtensionAttributes()
: $this->extensionFactory->create();
$extensionAttribute->setStores($this->_getStores());
Чем переопределенный magento/module-checkout/view/frontend/web/template/shipping.html и добавлен код для рендеринга местоположений
<td class="col col-stores">
<!-- ko if: method.carrier_code + '_' + method.method_code == 'pickup_from_store_pickup_from_store' -->
<div class="available-stores" data-bind="visible: $parent.isSelected() == 'pickup_from_store_pickup_from_store'">
<div class="store-search-input">
<input type="text">
</div>
<div
class="store-list"
data-bind="foreach: method.extension_attributes.stores">
<div class="store-row">
<label>
<input type="radio"
data-bind="
value: $data.id,
checked: $parentContext.$parent.selectedStore(),
attr: {
'id': 'store_id_' + $data.id,
'name': 'offline_store'
},
click: $parentContext.$parent.selectStore.bind(this, $data.id)
"
class="radio"/>
<span data-bind="text: $data.name"></span>
</label>
</div>
</div>
<div id="map"></div>
</div>
<!-- /ko -->
Мне нужно чтобы вставить карту Google в<div id="map"></div>
Я уже включил библиотеку карт Google в отдельный блок в файл phtml.
<script src="https://maps.googleapis.com/maps/api/js?key=some_key&libraries=geometry"></script>
И в этот шаблон добавлен также js, который работает с google api
<script type="text/x-magento-init">
{
"*": {
"Company_StoreSearch/js/store-search": {
"stLocation": <?php echo $block->getStoreListJsonArray() ?>,
"lpgLocation": <?php echo $storesByType['lpg'] ?>,
"gardenLocation": <?php echo $storesByType['garden'] ?>,
"extensiveToolSelectionLocation": <?php echo $storesByType['extensive_tool_selection'] ?>,
"perishableLocation": <?php echo $storesByType['perishable'] ?>,
"servicePointsLocation": <?php echo $storesByType['service_points'] ?>,
"markerUrl": "<?php echo $block->getMarkerImageUrl() ?>",
"locationMarkerUrl": "<?php echo $block->getLocationImageUrl() ?>",
"searchUpdate": "<?php echo $block->getSearchUpdateUrl() ?>"
}
}
}
И добавил этот блок как дочерний в "checkout.root" в checkout_index_index.xml . Чем отображать этот блок в файле onepage.phtml, например
<?php echo $block->getChildHtml('store_search_map') ?>
В конце шаблона
Но я не понимаю, как я могу отображать карты Google. Страница оформления заказа отображается с использованием knockout js и когда я хотите применить google maps api к моему div в shipping.html - его еще не существует. Я попытался использовать $(документ).ajaxStop(функция(){...}), DOMReady! в качестве параметра в моем пользовательском js. Но ничего не помогает. Пожалуйста, помогите мне. Спасибо.
1 answers
Я работал над применением автозаполнения места при оформлении заказа, и вот фрагмент с моим кодом:
<script src="https://maps.googleapis.com/maps/api/js?key=lll&libraries=places&callback=notifySubscribers"
async
defer></script>
<script>
var notifySubscribers = function () {
require(['GoogleAddressLookup/model/apiLoadListener'], function (loadListener) {
loadListener.isGoogleApiLoaded(true);
})
};
</script>
И мое объяснение. Этот phtml отображается в контейнере after.body.start, и, как вы можете видеть, я в основном выполняю асинхронную загрузку библиотеки google. Важной частью является то, что я передаю функцию обратного вызова уведомляющим подписчикам. Там, как вы можете видеть, я загружаю свой класс apiloadlistener, который предназначен для хранения информации о состоянии скрипта в isGoogleApiLoaded ko observable. ApiLoadListener сам по себе определяется в отдельном файле. Поскольку свойство isGoogleApiLoaded равно ko.observable, я могу загрузить модуль apilistener в любой другой модуль, в котором я могу подписаться на обратный вызов и выполнить соответствующую логику. В вашем случае это будет инициализация карты Google для определенного элемента. Я делаю это в рамках обратного вызова onElementRender, вот пример фрагмента:
onElementRender: function (el) {
if (!loadListener.isGoogleApiLoaded()) {
loadListener.subscribe((isApiLoaded) => {
if (isApiLoaded) {
this.initializer = new Initializer(el, Strategy, this.autocomplete_id);
}
});
} else {
this.initializer = new Initializer(el, Strategy, this.autocomplete_id);
}
},
Как вы можете видеть, не обращая внимания на неизвестные классы, я в основном слушаю отправку событий из Загрузчик для выполнения моей логики. Я надеюсь, что это поможет вам.