2

I have been experimenting with a custom module with KnockoutJs on the frontend in M2.

I've created two components: a ProductPackage and a ProductPackagePopop. Functionally, the ProductPackage triggers a modal that renders some details about the package's children.

These two components share quite the same logic which I would like to share between the components. For example, both have a function initTranslation which retrieves the right translations for this store id.

Since I am new to the magento2 Knockout implementation, is there some way to create a base component from which my two components inherit the shared logic? Or a trait like in PHP. I've looked at mixins, but it seems to me it's more fit to extend external is.

define(['uiComponent'], function (Component) {
 return Component.extend({
 store_id: 0,
 initialize: function (config) {
 this.store_id = config.store_id;
 this.initTranslations(config.productPackage);
 },
 initTranslations: function (productPackage) {
 //some logic here
 },
 children: function(){
 // retrieves children
 }
 });
});

I've found this: https://stackoverflow.com/questions/16569810/knockout-viewmodel-base-class-javascript-inheritance , but I find it hard to fit that in the M2 Knockout/RequireJs wrapper.

Rajeev K Tomy
17.3k6 gold badges64 silver badges104 bronze badges
asked May 24, 2021 at 9:40

1 Answer 1

3

To do this, you need to create basically 3 components.

  1. Your base component. I am calling this BasePackage.
  2. ProductPackage component
  3. ProductPackagePopop component.

Now make ProductPackage and ProductPackagePopop extend from your base component BasePackage.

So inaction, if your module is My_Example. Then your components should somewhat look like below:

Your base component

File: app/code/My/Example/view/frontend/web/js/base-package.js

define(['uiComponent'], function (Component) {
return Component.extend({
 // this is your common method
 initTranslations: function (productPackage) {
 //some logic here
 },
 
 // put your common methods here in this base component
});

Your ProductPackage component

File: app/code/My/Example/view/frontend/web/js/product-package.js

define(['My_Example/js/base-package'], function (BasePackageComponent) {
return BasePackageComponent.extend({
 initialize: function (config) {
 this.store_id = config.store_id;
 this.initTranslations(config.productPackage);
 },
});

Here this component now extends from the BasePackage component. Due to this this.initTranslations() will be referred from the BasePackage component unless you define the same method inside your children's component such as this.

If in case, you need to define the same method inside this component, then calling this._super() will be invoking the parent method.

Your ProductPackagePopop component.

In a similar line, this component will look like the above.

File: app/code/My/Example/view/frontend/web/js/product-package-popop.js

define(['My_Example/js/base-package'], function (BasePackageComponent) {
return BasePackageComponent.extend({
 initialize: function (config) {
 this.store_id = config.store_id;
 this.initTranslations(config.productPackage);
 },
});

I hope you get the idea.

answered May 24, 2021 at 10:11
1
  • 1
    Nice! Thank you, i was experimenting with mixins, which worked, but it seemed like not the right tool for the job. This is exactly what i meant. Thanks! Commented May 24, 2021 at 10:22

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.