merkle-open / gondel

🚡 Gondel is a tiny library to bootstrap frontend components
https://gondel.js.org
MIT License
36 stars 10 forks source link

Events to not bubble up / will not be triggered on child components #53

Closed patricklehmann closed 5 years ago

patricklehmann commented 5 years ago

Type of issue


Expected behavior

When i click on a button within the parent component the public event is triggered on the child components as well.

Current behavior

A event triggered by triggerPublicEvent on a parent component won't be triggered on a child component.

Steps to reproduce the behavior

<div data-g-name="ParentComponent">
    <div class="m-parent-component__children-wrapper">
        <div data-g-name="ChildComponent">
        </div>
        <div data-g-name="ChildComponent">
        </div>
        <div data-g-name="ChildComponent">
        </div>
    </div>

    <div class="m-parent-component__child-switcher">
        <button class="m-parent-component__child-switch" data-index="1" />
        <button class="m-parent-component__child-switch" data-index="2" />
        <button class="m-parent-component__child-switch" data-index="3" />
    </div>
</div>
export enum Selectors {
    SLIDE_INDICATOR = '.m-parent-component__child-switch'
}

export enum Events {
    SLIDE_ENABLED = 'gParentComponent.slideEnabled'
}

export enum States {
    ACTIVE = 'state--m-child-component-active'
}

@Component('ParentComponent')
export class ParentComponent extends GondelBaseComponent {
    @EventListener('click', Selectors.SLIDE_INDICATOR)
    _handleClick(event) {
        console.log('ParentComponent._handleClick');

        triggerPublicEvent(Events.SLIDE_ENABLED, this);
    }
}

@Component('ChildComponent')
export class ChildComponent extends GondelBaseComponent {

    @EventListener(Events.SLIDE_ENABLED)
    _handleSlideEnabled(event) {
        console.log('_handleSlideEnabled');
        this._ctx.classList.add(States.ACTIVE);
    }
}
janwidmer commented 5 years ago

Hey @patricklehmann, The current behaviour is intentionally implemented like that. Events only bubble up the DOM tree (as also native events do).

For your example, the proper way would be to implement a public method in your child component, which set's the States class.

You can then use this public method in your parent component by using the gondel core function findComponents to get the instance of your child component to call the public methd

patricklehmann commented 5 years ago

@janwidmer i'll give it a try and reply to you!

janwidmer commented 5 years ago

@patricklehmann you can find detailed example about the functionality here: https://gondel.js.org/docs/communication.html

The event feature is only intended to be used when you don't have a handle on the dom node of that component AND it is a parent of the current component.

I use it mostly to to things on my page controller component, e.g. enabling / disabling scrolling.. Most cases can and should be handled by calling public methods on the components.

patricklehmann commented 5 years ago

@janwidmer great! That's a working solution. It this "the way to go with gondel"? Thanks for your fast reply.

janwidmer commented 5 years ago

@patricklehmann yes, working with public method's to communicate is the way to go with gondel in most cases. It should lead to a more strict interaction of components..