Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Multiple inheritance with custom shapes not working (as expected?) #2302

Closed
alexandernst opened this issue Aug 15, 2023 · 7 comments
Closed
Labels

Comments

@alexandernst
Copy link
Contributor

What happened?

I'm playing with the examples at https://resources.jointjs.com/tutorial/ts-shape and I figured out I'd try to create a Base shape that extends from dia.Link, which then I'd use to create MyLink. It turns out this doesn't work.

I'm not really sure why (maybe it has something to do with the way defaults is being called?).

Demo: https://codesandbox.io/s/joint-custom-link-extend-playground-ngs9zn

Note that

class CLink extends CBase {                       // <--- doesn't render the link

class CLink extends joint.shapes.standard.Link {  // <--- renders the link

Version

3.7.5

What browsers are you seeing the problem on?

Firefox, Chrome, Safari

What operating system are you seeing the problem on?

Mac

@kumilingus
Copy link
Contributor

It is the defaults :)

  • wrong order of merge arguments
  • super.default is a function in CBase
class CLink extends CBase {
  defaults() {
    return joint.util.merge(
      {},
      super.defaults(),
      {
        type: "CLink",
        attrs: {
          line: {
            stroke: "#ccc",
            strokeWidth: 2
          }
        }
      },
    );
  }
}

@alexandernst
Copy link
Contributor Author

Ooohh! 🤔

Ok, I have another questions. Why CBase is merging super.defaults, but CLink is merging super.defaults()? What is the difference between using super.defaults as a value and calling super.defaults() as a function?

@kumilingus
Copy link
Contributor

kumilingus commented Aug 15, 2023

The shapes.standard.Link class is defined via the define method which using the extend method of Backbone. If you create a Backbone.Model this way (ES5 way), the defaults is a property, not a method. Therefore CBase needs to access it as a property.

The ES Class CBase defines the defaults as a method. Therefore CLink has to call it as a function.

I recommend reading this article which should explain this in detail. Also reading this Backbone issue might be helpful.

@alexandernst
Copy link
Contributor Author

Oohh, now I get it. Good thing to know :)
Thank you!!

@alexandernst
Copy link
Contributor Author

alexandernst commented Aug 20, 2023

I have an extra question 🙏

Would it be possible to extend from 2 classes using this method? Lets say that I have CBaseLinkA which defines the stroke color (using the defaults()) and CBaseLinkB which defines the strokeWidth (also using the defaults()) and the markup attribute. Would it be possible to do something like

class MyLink extends merge(CBaseLinkA, CBaseLinkB) {
  defaults() {
    return joint.util.merge(
      {
        attrs: { line: { fill: "red" } }
      },
      super.defaults() // ???? 
    )
  }
}

@kumilingus
Copy link
Contributor

Perhaps you can check this discussion.

@alexandernst
Copy link
Contributor Author

Hmmm, I think I saw similar stuff in SO, but I'm not really sure how to handle the defaults(), since that is threated in a very special way. I'll play around and report back if I find a way of achieving this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants