Update attributes of child components

Asked

Viewed 267 times

0

I’m making a very simple accordion component. A list of items where I click on one and it opens; if you already have one, it closes and the other opens.

<ns-accordion-item is-show="false">
  <accordion-head>
    <h3> Este títlulo pode conter o que quizer</h1>
  </accordion-head>
  <accordion-body>
      <form>[...]</form>
  </accordion-body>
</ns-accordion-item>

This little guy is a very simple component, he transcludes <accordion-head> and <accordion-body>. The body has a ng-if of the prop is-show (bind '='), so only display content when needed.

I want to create another component, the <ns-accordion>. The idea is that he controls and leaves only one <ns-accordion-item> open.

Then it would be something like this:

<ns-accordion>
  <ns-accordion-item>[...]</ns-accordion-item>
  <ns-accordion-item>[...]</ns-accordion-item>
  <ns-accordion-item>[...]</ns-accordion-item>
</ns-accordion>

And now I can’t make the magic happen.

I tried to get the <ns-accordion> alter the attr is-open of <ns-accordion-item> there at the $postLink

ctrl.$postLink = function() {
  $currentAccordion = $element.find('ns-accordion-item[is-show="true"]');

  $element.on('click', 'ns-accordion-item', function(){
    var $el = angular.element(this);
    $currentAccordion.attr('is-show', false);
    $currentAccordion = $el.attr('is-show', true);
  });
};

Although it changes the attribute, the accordion-item ignores this change and does not fire the $onChange.

Does anyone know where I’m going wrong? That’s the good solution?

1 answer

1

You can use $emit in the $scope of their ns-accordion-item to notify the ns-accordion when they are clicked, so the ns-accordion uses $broadcast to notify the ns-accordion-item that they should close.

The $emit issue an event to the parent scopes from which it was issued.

The $broadcast issue an event to the child scopes from which it was issued.

So you get your components to talk to their proper scope trees. Maybe it’s a problem if you enter a set of ns-accordion and ns-accordion-item, but then you can do a workaround using ids for ns-accordion.

Doc $emit https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$emit

Doc $broadcast https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$broadcast

  • thanks. It’s like Pubsub, mass I thought of something else too. When we created a form the scope father gets a prop with the form name. So I thought I’d do something like this: <ns-accordion name="acc"> <ns-accordion-item name="sub1" is-open="$acc.sub1.isOpen"> What do you think?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.