Angular2 access parent DOM element attribute

Viewed 1789

How do I access [attr.open]="false" from the div "child_div". In short I want to emulate the code sample below, but I don't know how to access parent attr from child div.

<div class="parent_div" *ngFor="let level_1 of [1,2,3]" [attr.open]="false">
   <div class="chlid_div" *ngIf="parent.attr.open">

       <div class="parent_div" *ngFor="let level_2 of [1,2,3]"
       [attr.open]="false">
          <div class="chlid_div" *ngIf="parent.attr.open">
             content
          </div>
       </div>

   </div>
</div>
6 Answers

You can make use of the Following Template

<div [attr.open]="my()">
   <div class="chlid_div" *ngIf="data">content</div>
</div>

Component

export class AppComponent {
  data: boolean;


  my() {
    this.data = true;
  }

}

Working Example

I didn't get what you wanted, don't you need an input and output to exchange a variable ?

I think you wanted to do something like this, don't you ?

<app-parent *ngIf="data">
  <app-child [myInput]="toChildren(value)" (toParent)="toParent(value)" 
       class="chlid_div">content</app..>
</app..>

You cannot refer to the child element inside of its own ngIf directive because, as the expression is being evaluated, that element doesn't exist yet. Therefore, it cannot be used to get its parent.

One way to refer to the parent div is with a template reference variable. However, if you try to use #parentDiv in ngIf as in the following example:

<div #parentDiv [attr.open]="true">
    <div class="chlid_div" *ngIf="parentDiv.getAttribute('open') === 'true'">content</div>
</div>

Angular will throw an ExpressionChangedAfterItHasBeenCheckedError (see this plunker). The explanation for that problem is given in this answer by AngularInDepth.com.

One way to avoid that problem is to refer to members of the component class inside of the ngIf directive, instead of trying to refer to the DOM elements.

You can try to using the following code:

<div class="parent_div" *ngFor="let level_1 of [1,2,3]" [attr.open]="false">
    <!-- You need the #child -->
    <div class="chlid_div" *ngIf="child.parent.attr.open" #child>

        <div class="parent_div" *ngFor="let level_2 of [1,2,3]" [attr.open]="false">
            <div class="chlid_div" *ngIf="parent.attr.open">
                content
            </div>
        </div>
    </div>
</div>

you can just bind them to the same variable in your component

<div class="parent_div" *ngFor="let level_1 of [1,2,3]" 
 [attr.open]="myVariable">
   <div class="chlid_div" *ngIf="myVariable">

Furthermore, each component each has it's own scope, so the variables will automatically be mapped to the correct parent.. In other words, if you have 10 of these on the page, the angular component is smart enough to know myVariable only applies to the scope of the 1 component and only the 1 component will be affected.

Related