微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Magento Knockout 使用计算函数动态索引产品数据数组

如何解决Magento Knockout 使用计算函数动态索引产品数据数组

所以我试图在 M2 主页上制作一种特定类型的“产品卡”块。 这个想法是在下拉列表中包含当前所选产品的产品详细信息的块

layout

我实施了以下文件来尝试实现这一目标:

app/code/vendor/Module/view/frontend/web/js/view/subscriptions-group.js

/**
 * @category vendor
 * @package vendor\Module
 * @copyright copyright (c) 2021 vendor Media Limited (http://www.vendor.co.uk/)
 * @license http://opensource.org/licenses/afl-3.0.PHP Academic Free License (AFL 3.0)
 */

define([
    'uiElement','underscore','jquery','ko','mage/translate','Magento_Ui/js/model/messageList'
],function (Element,_,$,ko,$t,messageList) {
    'use strict';

    return Element.extend({
        defaults: {
            template: 'vendor_Module/products-group',productGroup: null,ajaxHttpMethod: 'POST',productsRendered: 0,productData: ko.observableArray([]),currentId: ko.observable(0),currentProduct: ko.pureComputed(function () { return {};}).bind(this),imports: {
                ajaxUrl: '${ $.provider }:ajaxUrl',showDescription: '${ $.provider }:showDescription'
            }
        },loadingInProgress: ko.observable(false),errorMessage: ko.observable(null),warningMessage: ko.observable(null),initialize: function () {
            this._super();
            ko.options.deferUpdates = true;
            let self = this;

            this.currentProduct = ko.pureComputed(function (){
                return self.productData[self.currentId()] || {};
            },self).bind(this);

            this.getProductData()
                .done(function(response) {
                    Object.values(JSON.parse(response)).forEach(function(product) {
                        self.productData.push(product);
                    });
                    self.currentId.valueHasMutated();
                    console.log(self.currentProduct());
                },self)
                .fail(function(err) {
                    console.error(`Failed to get product data for group ${ self.productGroup }`);
                    console.error(err.message);
                },self);

            return this;
        },getProductData: function() {
            return $.ajax({
                accepts: {
                    text: "application/json"
                },url: this.ajaxUrl,type: this.ajaxHttpMethod,dataType: 'json',data: {
                    group: this.productGroup
                }
            })
        }
    });
});

app/code/vendor/Module/view/frontend/templates/subscription-list.phtml

/** @var Subscriptions $block */
$_productCollection = $block->getProducts();
/** @var vendor\Module\Helper\Config $_configHelper */
$_configHelper = $this->helper(ConfigHelper::class);

// display deFinitions
$viewmode = 'list';
$image = 'category_page_list_image';
$showDescription = true;
$i = 0;
?>
<?PHP if (!$_productCollection || !count($_productCollection)): ?>
    <div class="message info empty">
        <div><?PHP
            echo __('You do not have any subscriptions.') ?></div>
    </div>
<?PHP else: ?>
    <div class="products wrapper <?= $viewmode ?> products-<?= $viewmode ?>" data-bind="scope: 'subscriptionsList'">
        <ol class="products list items product-items">
            <!-- ko foreach: elems() -->
                <li class="item product product-item product-item-info" data-container="product-grid" data-bind="template: { name: getTemplate(),data: currentProduct}">
                </li>
            <!-- /ko -->
        </ol>
    </div>
<?PHP endif; ?>
<script>
    window.subscriptionConfig = <?= Zend_Json::encode($block->getSubscriptionConfig()) ?>;
</script>
<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "subscriptionsList": {
                    "component": "vendor_Module/js/view/subscriptions-list","config": {
                        "ajaxUrl": "<?= $block->getUrl($_configHelper::PRODUCT_DATA_AJAX_URL) ?>","showDescription": "<?= json_encode($block->showDescription()) ?>","viewmode": "<?= $viewmode ?>","image": "<?= $image ?>"
                    },"children": {
                        "groupListIncontrol": {
                            "component": "vendor_Module/js/view/subscriptions-group","config": {
                                "provider": "subscriptionsList","productGroup": "<?= $_configHelper::PRODUCT_GROUP_INCONTROL ?>"
                            }
                        },"groupListOnlinePack": {
                            "component": "vendor_Module/js/view/subscriptions-group","productGroup": "<?= $_configHelper::PRODUCT_GROUP_ONLINE_PACK ?>"
                            }
                        }
                    }
                }
            }
        }
    }
}
</script>

app/code/vendor/Module/view/frontend/web/template/products-group.html(这个正在从纯PHP转ko的过程中,看起来乱七八糟,抱歉强>)

<!--
 @category vendor
 @package vendor\Module
 @copyright copyright (c) 2021 vendor Media Limited (http://www.vendor.co.uk/)
 @license http://opensource.org/licenses/afl-3.0.PHP Academic Free License (AFL 3.0)
 -->
<!--Fix product group to be dynamic-->
<!--<ol class="products list items product-items" data-bind="class: productGroup">-->
<!--    <div class="top-product-container">-->
<!--        <span class="name-wrapper" data-bind="accessObj: {  obj: currentProduct,key: 'name' } "></span>-->
<!--&lt;!&ndash;        <?PHP  echo $block->getProductPrice($_product) ?>&ndash;&gt;-->
<!--        <div class="price-Box price-final_price" data-role="priceBox" data-product-id="5406" data-price-Box="product-id-5406">-->
<!--            <span class="price-container price-final_price tax weee">-->
<!--                <span id="product-price-5406" data-price-amount="99" data-price-type="finalPrice" class="price-wrapper "><span class="price" data-bind="accessObj: {  obj: currentProduct,key: 'price' }"></span></span>-->
<!--            </span>-->
<!--        </div>-->
<!--    </div>-->
<!--</ol>-->

<span class="stripped-name" data-bind="text: nameStripped" style="display: none;"></span>
<div class="top-product-container">
<!--        <?PHP  echo $block->getProductPrice($_product) ?>-->
    <label for="select_subscription_<?PHP echo $i ?>" class="product name product-item-name">
        <span class="name-wrapper" data-bind="text: name"></span>
    </label>
    <div class="price-Box price-final_price" data-role="priceBox" data-product-id="5406" data-price-Box="product-id-5406">
        <span class="price-container price-final_price tax weee">
            <span id="product-price-5406" data-price-amount="99" data-price-type="finalPrice" class="price-wrapper "><span class="price" data-bind="text: getCurrentAttribute('price')"></span></span>
        </span>
    </div>
</div>
<div class="info-container">
    <div class="product-image" data-bind="text: getCurrentAttribute('imageHtml')">
    </div>
    <div class="info-block">
        <?PHP if ($showDescription):?>
        <div class="product description product-item-description">
            <?PHP echo $_helper->productAttribute($_product,$_product->getShortDescription(),'short_description'); ?>
            <?PHP $longDesc = $_helper->productAttribute($_product,$_product->getDescription(),'description'); ?>
            <?PHP if ($longDesc): ?>
            <?PHP if (!$block->showDescription()): ?>
            <a onclick="jQuery(this).next().toggle(); jQuery(this).hide();" title="<?PHP  echo $_productNameStripped ?>" class="action more">
                <?PHP echo __('Read More...'); ?>
            </a>
            <?PHP endif; ?>
            <div class="long-desc" <?PHP if ($block->showDescription()): ?>style="display: block;"<?PHP endif; ?>>
            <?PHP echo $longDesc; ?>
        </div>
        <?PHP endif; ?>
    </div>
    <?PHP endif; ?>
    <?PHP if ($note = $_helper->productAttribute($_product,$_product->getProductNote(),'product_note')): ?>
    <div class="note">
        <?PHP echo $note ?>
    </div>
    <?PHP endif; ?>
</div>
</div>

在 UiComponent 中,我正在调用一个 M2 JSON 控制器,该控制器返回一个 JSON 对象列表,每个对象都是要为 product_id 呈现的所有相关产品数据。我已经用调试器测试过这个数据到达

所以它有两个问题:

  1. subscriptions-list.phtml 不喜欢 data-bind="template: { name: getTemplate(),data: currentProduct}",它说“无法读取未定义的属性名称”。我尝试根据 this answer
  2. 的建议创建此模板绑定
  3. 页面加载两个 this.productData 可观察数组时,尽管我亲眼验证了它们得到了不同的数据响应(调试器),但它们显示完全相同的数据。在我看来,这个属性在孩子之间以某种方式共享,因为它最终连接了从控制器返回的两个数组

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。