简体   繁体   中英

Update dom after component rendered the view, best practice in Angular2?

I'm seeking some advice how I should handle elements when working with Angular2. I have stored some elements id's in the localstorage, and want to set a selected class name on some specific elements.

For now I'm using this way:

ngAfterViewChecked() {

// Check if seats has been selected before
var selectedSeats: elementInterface = JSON.parse(localStorage.getItem('SelectedSeats'));

if (selectedSeats != null) {
  var outboundElement = document.getElementById(selectedSeats.outboundSelectedElement);
  var returnElement = document.getElementById(selectedSeats.returnSelectedElement);

  this.autoSelectSeats(outboundElement);
  this.autoSelectSeats(returnElement);
}

}

Method:

private autoSelectSeats(element: Element) {
    // Set selected class on element
    element.classList.add('selected');
}

I see two issues here. The first is the ngAfterViewChecked hook that fires more than once after the view is created. Is there something I can do so it only fires once?

Second: Is there a better way to get the element when you know the id and set a class attribute on it after the content has loaded?

I can't seem to find the Angular2 way of doing it, besides using this hook.

Any idea? Also, please don't post Jquery posts, as I don't want to implement that when using Angular :)

How about adding a custom directive to each of your "seat" elements and let that directive add the CSS class?

In your template , the directive would be used as follows (I'm guessing, since you didn't show your template):

<div *ngFor="let seat of seats" [highlight]="seat.id">
  ...
</div>

You need to pass some information to the directive to identify which seat it is working on. It seems better to pass an id directly (eg seat.id ) rather than to rely on HTML ids (although in your case they might be one and the same).

Now the code for the directive :

@Directive({
  selector: '[highlight]'
})
export class HighlightDirective {
  @Input() highlight: string;  // This will contain a seat.id

  constructor(el: ElementRef, ss: SeatService) {
    const selectedSeats = ss.getSelectedSeats();
    // If current seat found in selectedSeats, mark it as selected.
    if (selectedSeats.indexOf(this.highlight) !== -1) {
      this.el.nativeElement.classList.add('selected');
    }
  }
}

The reason I'm using an external service SeatService to get the data from localStorage is that Angular will create an instance of HighlightDirective for every match it finds in your template. You don't want to refetch the selected seats in every instance (the service lets you cache the seats and return the same data).

Angular方式有很好的文档,使用以下语法切换类: [class.selected]="selected"

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