Knockout是一个遵循MVVM(模型 - 视图 - 视图 - 模型)模式的javascript库,用于创建前端。您可以使用Knockout JS轻松处理复杂的数据驱动接口,并且由于它是开源的,因此可以免费使用。

Knockout JS是轻量级的,主要用在Magento 2的结帐页面。但是Knockout JS在Magento 2中实现起来有点复杂,因此,本教程将教你如何在Magento 2产品页面上中实现Knockout JS。

Magento 2在产品页面上提供了一个简单的数量输入文本,为了使客户更容易操作,您可以在Magento 2中添加增量和减量按钮。我将使用自定义模块实现它,

开始吧!

配置模块

通过在app/code/Alwayly/AddQuantityIncrement/etc中创建module.xml文件来配置模块。在其中添加以下代码:

	<?xml version="1.0"?>
	<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
	<module name="Alwayly_AddQuantityIncrement" setup_version="1.0.0"></module>
	</config>

模块注册

现在通过在app/code/Alwayly/AddQuantityIncrement中创建registration.php来注册模块,并在其中添加以下代码:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
   \Magento\Framework\Component\ComponentRegistrar::MODULE,
   'Alwayly_AddQuantityIncrement',
   __DIR__
);

复制addtocart.phtml

从magento安装的根目录转到vendor/magento/module-catalog/view/frontend/templates/product/view并将addtocart.phtml复制到您自己的模块pp/code /Alwayly/AddQuantityIncrement/view/frontend/templates/catalog/product/view。addtocart.phtml文件将是这样的:

<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
/** @var $block \Magento\Catalog\Block\Product\View */
?>

<?php $_product = $block->getProduct(); ?>
<?php $buttonTitle = __('Add to Cart'); ?>
<?php if ($_product->isSaleable()): ?>
<div class="box-tocart">
   <div class="fieldset">
       <?php if ($block->shouldRenderQuantity()): ?>
       <div class="field qty">
           <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label>
           <div class="control">
               <input type="number"
                      name="qty"
                      id="qty"
                      maxlength="12"
                      value="<?php /* @escapeNotVerified */ echo $block->getProductDefaultQty() * 1 ?>"
                      title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty"
                      data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
                      />
           </div>
       </div>
       <?php endif; ?>
       <div class="actions">
           <button type="submit"
                   title="<?php /* @escapeNotVerified */ echo $buttonTitle ?>"
                   class="action primary tocart"
                   id="product-addtocart-button">
               <span><?php /* @escapeNotVerified */ echo $buttonTitle ?></span>
           </button>
           <?php echo $block->getChildHtml('', true) ?>
       </div>
   </div>
</div>
<?php endif; ?>
<script type="text/x-magento-init">
   {
       "#product_addtocart_form": {
           "Magento_Catalog/product/view/validation": {
               "radioCheckboxClosest": ".nested"
           }
       }
   }
</script>
<?php if (!$block->isRedirectToCartEnabled()) : ?>
<script type="text/x-magento-init">
   {
       "#product_addtocart_form": {
           "catalogAddToCart": {
               "bindSubmit": false
           }
       }
   }
</script>
<?php endif; ?>

编辑addtocart.phtml

addtocart.phtml中,创建一个UI组件并对其进行初始化。要做到这一点,首先在数量的input字段上方添加以下脚本:

<script type="text/x-magento-init">
{
   "*": {
           "Magento_Ui/js/core/app": {
               "components": {
                   "qty_change": {
                       "component": "Alwayly_AddQuantityIncrement/js/view/product/view/qty_change",
                       "defaultQty": <?php echo $block->getProductDefaultQty() * 1 ?>
                   }
               }
           }
   }
}
</script>

现在将组件qty_change与以下前端HTML连接:

<div class="control" data-bind="scope: 'qty_change'">
   <button data-bind="click: decreaseQty">-</button>
   <input  data-bind="value: qty()"
   type="number"
   name="qty"
   id="qty"
   maxlength="12"
   title="<?php echo __('Qty') ?>"
   class="input-text qty"
   data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
   />
   <button data-bind="click: increaseQty">+</button>
</div>

Data-bind 属性:使用我们的组件qty_change的Javascript函数连接HTML。

在上面的代码中,有两个按钮,我通过使用Javascript点击事件连接到组件,将用于减少/增加数量值。最终的addtocart.phtml文件如下所示:

<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
/** @var $block \Magento\Catalog\Block\Product\View */
?>

<?php $_product = $block->getProduct(); ?>
<?php $buttonTitle = __('Add to Cart'); ?>
<?php if ($_product->isSaleable()): ?>
<div class="box-tocart">
   <div class="fieldset">
       <?php if ($block->shouldRenderQuantity()): ?>
       <div class="field qty">
           <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label>

<script type="text/x-magento-init">
{
   "*": {
           "Magento_Ui/js/core/app": {
               "components": {
                   "qty_change": {
                       "component": "Alwayly_AddQuantityIncrement/js/view/product/view/qty_change",
                       "defaultQty": <?php echo $block->getProductDefaultQty() * 1 ?>
                   }
               }
           }
   }
}
</script>

<div class="control" data-bind="scope: 'qty_change'">
   <button data-bind="click: decreaseQty">-</button>
   <input  data-bind="value: qty()"
   type="number"
   name="qty"
   id="qty"
   maxlength="12"
   title="<?php echo __('Qty') ?>"
   class="input-text qty"
   data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
   />

   <button data-bind="click: increaseQty">+</button>
</div>
       </div>
       <?php endif; ?>
       <div class="actions">
           <button type="submit"
                   title="<?php /* @escapeNotVerified */ echo $buttonTitle ?>"
                   class="action primary tocart"
                   id="product-addtocart-button">
               <span><?php /* @escapeNotVerified */ echo $buttonTitle ?></span>
           </button>
           <?php echo $block->getChildHtml('', true) ?>
       </div>
   </div>
</div>
<?php endif; ?>
<script type="text/x-magento-init">
   {
       "#product_addtocart_form": {
           "Magento_Catalog/product/view/validation": {
               "radioCheckboxClosest": ".nested"
           }
       }
   }
</script>
<?php if (!$block->isRedirectToCartEnabled()) : ?>
<script type="text/x-magento-init">
   {
       "#product_addtocart_form": {
           "catalogAddToCart": {
               "bindSubmit": false
           }
       }
   }
</script>
<?php endif; ?>

创建qty_change.js

现在在app/code/Alwayly/AddQuantityIncrement/view/frontend/web/js/view/product/view中创建qty_change.js。在其中添加以下代码:

define([
   'ko',
   'uiComponent'
], function (ko, Component) {
   'use strict';
   return Component.extend({
       initialize: function () {
           //initialize parent Component
           this._super();
           this.qty = ko.observable(this.defaultQty);
       },
       decreaseQty: function() {
           var newQty = this.qty() - 1;
           if (newQty < 1) 
           {
               newQty = 1;
           }
           this.qty(newQty);
       },
       increaseQty: function() {
           var newQty = this.qty() + 1;
           this.qty(newQty);
       }
   });
});

创建catalog_product_view.xml

最后,只需在app/code/Alwayly/AddQuantityIncrement/view/frontend/layout中创建catalog_product_view.xml即可。在其中添加以下代码:

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <body>
       <referenceBlock name="product.info.addtocart">
           <action method="setTemplate">
               <argument name="template" xsi:type="string">Alwayly_AddQuantityIncrement::catalog/product/view/addtocart.phtml</argument>
           </action>
       </referenceBlock>
       <referenceBlock name="product.info.addtocart.additional">
           <action method="setTemplate">
               <argument name="template" xsi:type="string">Alwayly_AddQuantityIncrement::catalog/product/view/addtocart.phtml</argument>
           </action>
       </referenceBlock>
   </body>
</page>

上面代码的目的是更改默认的addtocart.phtml模板。

运行命令

使用SSH终端转到magento安装的根目录,然后运行以下命令:

rm -rf var/di var/generation var/cache/* var/log/* var/page_cache/*

php bin/magento module:enable Alwayly_AddQuantityIncrement

php bin/magento setup:upgrade

php bin/magento setup:di:compile

php bin/magento indexer:reindex

php bin/magento cache:clean

php bin/magento cache:flush

现在转到产品页面,您将看到结果:

Note:我们已在Magento 2.3上测试了上述代码.