简体   繁体   中英

Using getElementById to select element in parent component - Angular 5

I'm trying to select an element in a parent component, from a child component.

In my child component I have the following code:

 removeItem(outcome) {
    const el = (<HTMLInputElement>document.getElementById(outcome.id));
    el.classList.remove("selected-bet");
    //...
  }

and the item I am trying to select is the id (outcome.id) that is in the parent component:

     <ng-container *ngFor="let outcome of market.Outcomes">
          <div class="market-cell-3" id="{{outcome.id}}">
            <span class="market-name">{{ outcome.name}}.</span>
          </div>
     </ng-container>

When I try the above code, el is always null and I get the following error

BetSlipComponent.html:78 ERROR TypeError: Cannot read property 'classList' of null

What is the correct way to do this?

To give some more details about the structure of the app: The parent controller displays a list of sporting markets, and the child component is like a shopping cart. When a user selects a market in the parent, a class is added (selected-bet) and it is added to the cart. There is a remove button (removeItem(outcome)) in the cart and its from there I am experience the problem.

Don't try to touch the DOM manually when using Angular. It's wrong on every level. For example, you can bind to a class of an element like this:

<ng-container *ngFor="let outcome of market.Outcomes">
    <div class="market-cell-3" [class.selected-bet]="!outcome.removed">
        <span class="market-name">{{ outcome.name}}.</span>
    </div>
</ng-container>


removeItem(outcome) {
    outcome.removed = true;
}

I actually found some help from here . While it works, I'm not convinced its the right way to do it. I used an Output EventEmitter in the child component to send the id to the parent:

@Output() removeBetSelected = new EventEmitter<number>();

And in the removeItem() I added this:

this.removeBetSelected.emit(outcome.outcomeId) 

Add it to the child component

<bet-slip (removeBetSelected)=removeBetSelected($event)></bet-slip>

And in the parent component I had this function which finds the correct object from the outcomes QueryList and remove the class:

@ViewChildren('outcome') outcomes:QueryList<any>;

  public removeBetSelected(outcomeId) { 
    const outcomeObj = this.outcomes.toArray().find(obj =>  obj.nativeElement.id == outcomeId );
    outcomeObj.nativeElement.classList.remove('selected-bet')
  }

While it works, this all seems mental just to remove a class. There surely is a better way.

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