0

I have followed this tutorial link

HOW TO USE KNOCKOUT JS ON A MAGENTO 2 FRONTEND PAGE.

Magenest/KnockoutJs/etc/frontend/routes.xml :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
   <router id="standard">
       <route id="knockout" frontName="knockout">
           <module name="Magenest_KnockoutJs" />
       </route>
   </router>
</config>

Magenest/KnockoutJs/view/frontend/layout/knockout_test_index.xml :

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
     xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <head>
       <title>Knockout Js Testing Page</title>
   </head>
   <body>
       <referenceBlock name="content">
           <block class="Magenest\KnockoutJs\Block\Test" name="knockoutjs_test_block" template="test.phtml">
               <arguments>
                   <argument name="jsLayout" xsi:type="array">
                       <item name="components" xsi:type="array">
                           <item name="test" xsi:type="array">
                               <item name="component" xsi:type="string">Magenest_KnockoutJs/js/view/test</item>
                               <item name="displayArea" xsi:type="string">test</item>
                           </item>
                       </item>
                   </argument>
               </arguments>
           </block>
       </referenceBlock>
   </body>
</page>

Magenest/KnockoutJs/Block/Test.php :

<?php
namespace Magenest\KnockoutJs\Block;

use Magento\Framework\View\Element\Template;

class Test extends Template
{
   /**
    * @var array|\Magento\Checkout\Block\Checkout\LayoutProcessorInterface[]
    */
   protected $layoutProcessors;

   public function __construct(
       Template\Context $context,
       array $layoutProcessors = [],
       array $data = []
   ) {
       parent::__construct($context, $data);
       $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : [];
       $this->layoutProcessors = $layoutProcessors;
   }

   public function getJsLayout()
   {
       foreach ($this->layoutProcessors as $processor) {
           $this->jsLayout = $processor->process($this->jsLayout);
       }
       return \Zend_Json::encode($this->jsLayout);
   }

}

Magenest/KnockoutJs/Controller/Test/Index.php :

<?php
namespace Magenest\KnockoutJs\Controller\Test;

class Index extends \Magento\Framework\App\Action\Action
{

   protected $resultPageFactory;

   public function __construct(
       \Magento\Framework\App\Action\Context $context,
       \Magento\Framework\View\Result\PageFactory $resultPageFactory
   )
   {
       $this->resultPageFactory = $resultPageFactory;
       parent::__construct($context);
   }

   public function execute()
   {
       $resultPage = $this->resultPageFactory->create();
       return $resultPage;

   }
}

Magenest/KnockoutJs/view/frontend/templates/test.phtml :

<div id="test-div" data-bind="scope:'test'">
   <!-- ko template: getTemplate() --><!-- /ko -->
   <script type="text/x-magento-init">
       {
           "#test-div": {
               "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
           }
       }
   </script>

   <script>
       require([
           'mage/url',
           'Magento_Ui/js/block-loader'
       ], function(url, blockLoader) {
           blockLoader("<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-1.gif'); ?>");
           return url.setBaseUrl('<?php /* @escapeNotVerified */ echo $block->getBaseUrl();?>');
       })
   </script>
</div>

Magenest/KnockoutJs/view/frontend/web/js/view/test.js :

define([
   'ko',
   'uiComponent',
   'mage/url',
   'mage/storage',
], function (ko, Component, urlBuilder,storage) {
   'use strict';
   var id=1;

   return Component.extend({

       defaults: {
           template: 'Magenest_KnockoutJs/test',
       },

       productList: ko.observableArray([]),

       getProduct: function () {
           var self = this;
           var serviceUrl = urlBuilder.build('knockout/test/product?id='+id);
           id ++;
           return storage.post(
               serviceUrl,
               ''
           ).done(
               function (response) {
                   self.productList.push(JSON.parse(response));
               }
           ).fail(
               function (response) {
                   alert(response);
               }
           );
       },

   });
});

Magenest/KnockoutJs/view/frontend/web/template/test.html :

<button data-bind=" click: getProduct">Get Next Product</button>
<table>
   <thead>
   <tr>
       <th>ID</th>
       <th>Product Name</th>
       <th>Product Price</th>
       <th>Preview</th>
   </tr>
   </thead>
   <tbody data-bind="foreach: productList">
   <tr>
       <td data-bind="text: entity_id"></td>
       <td data-bind="text: name"></td>
       <td data-bind="text: price"></td>
       <td><img data-bind="attr: {src: src}" width="120" height="150" alt="Product Image"></td>
   </tr>
   </tbody>
</table>

Magenest\KnockoutJs\Controller\Test\Product.php :

<?php
namespace Magenest\KnockoutJs\Controller\Test;

use Magento\Catalog\Model\ProductFactory;
use Magento\Catalog\Helper\Image;
use Magento\Store\Model\StoreManager;

class Product extends \Magento\Framework\App\Action\Action
{
   protected $productFactory;
   protected $imageHelper;
   protected $listProduct;
   protected $_storeManager;

   public function __construct(
       \Magento\Framework\App\Action\Context $context,
       \Magento\Framework\Data\Form\FormKey $formKey,
       ProductFactory $productFactory,
       StoreManager $storeManager,
       Image $imageHelper
   )
   {
       $this->productFactory = $productFactory;
       $this->imageHelper = $imageHelper;
       $this->_storeManager = $storeManager;
       parent::__construct($context);
   }

   public function getCollection()
   {
       return $this->productFactory->create()
           ->getCollection()
           ->addAttributeToSelect('*')
           ->setPageSize(5)
           ->setCurPage(1);
   }

   public function execute()
   {
       if ($id = $this->getRequest()->getParam('id')) {
           $product = $this->productFactory->create()->load($id);

           $productData = [
               'entity_id' => $product->getId(),
               'name' => $product->getName(),
               'price' => '$' . $product->getPrice(),
               'src' => $this->imageHelper->init($product, 'product_base_image')->getUrl(),
           ];

           echo json_encode($productData);
           return;
       }
   }
}

Required Result : enter image description here

But Getting "404"

Complete Module Here

8
  • Please check my answer and let me know still, 404 return. Commented Jul 9, 2019 at 8:41
  • thank u let me check Commented Jul 9, 2019 at 8:44
  • 127.0.0.1/m2.3.0/knockout/test/index same "404". no success Commented Jul 9, 2019 at 8:49
  • Did you checked after update my answer? Check with cache clean and remove generated folder. Commented Jul 9, 2019 at 8:54
  • Now, It's working? Commented Jul 9, 2019 at 9:00

1 Answer 1

1

You didn't call your test.js file. Replace this below code in your test.phtml file in your <script type="text/x-magento-init">..</script>:

<script type="text/x-magento-init">
   {
       "*": {
        "Magento_Ui/js/core/app": {
           "components": {
                "test-div": {
                    "component": "Magenest_KnockoutJs/js/test"
                }
            }
        }

   }
</script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.