简体   繁体   中英

Ember JS: Call component action from another component

I am new to ember JS and after looking through the doc I still have no idea or don't understand how to achieve the following.

I have a navbar component that includes a menu button component

//components/nav-bar.hbs

<nav>
   <LinkTo class="btn-1" @route="contact"><span>Contact</span></LinkTo>
   <LinkTo class="btn-1" @route="about"><span>About</span></LinkTo>
   <MenuButton>Menu</MenuButton>
</nav>

When this button is clicked I would like to toggle another component which is not a parent nor a child of menu-button component, nor of the nav-bar component

//components/nav-aside.hbs
<div class="core_page_cover">

</div>
<aside class="core_menu_aside">

</aside>


//components/nav-aside.js
import Component from "@glimmer/component";
import { action } from "@ember/object";

export default class NavAsideComponent extends Component {
   @action
   toggle() {
       //toggle expanded | retracted class
   }
}

I have no idea how to call the toggle action when clicking on the button and I guess I am missing something...

The components are encapsulated like so

// .--------------navbar.hbs--------------    //
// <nav>
//   link link link link link link toggle-button  //
// </nav>
// <MenuAside/>

Thanks a lot.

The solution here is to move the state and the action to the common ancestor.

It seems you have 3 components:

  • navbar
  • nav-bar
  • nav-aside

Where basically navbar encapsulates both nav-bar and nav-aside :

so you have basically this in your navbar :

<NavBar />
<NavAside />

and inside the nav-bar you have a button that should toggle if something inside nav-aside is shown. Then the solution is to keep that information on the wrapping navbar component:

class NavbarComponent extends Component {
  @tracked showSomethingInAside = false;

  @action
  toggleShowSomethingInAside() {
    this.showSomethingInAside = !this.showSomethingInAside;
  }
}

And use it like this to call your components in navbar :

<NavBar @toggleSomethingInAside={{this.toggleShowSomethingInAside}} />
<NavAside @showSomethingInAside={{this.showSomethingInAside}} />

Then inside nav-bar you can use the action:

<button type="button" {{on "click" @toggleSomethingInAside}}>
  show something in aside
</button>

And inside nav-aside you can use the boolean:

{{#if @showSomethingInAside}}
  This can be toggled by the button in the other component
{{/if}}

So you see the solution is to always keep the state in the right place. If multiple components share a state (because one changes it and the other reads it) that state belongs in neither component but a common ancestor component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM