2015-07-01 8 views
28

Ich bin neu in Angular2 und Angular im Allgemeinen und versuche, einige jQuery zu feuern, nachdem die Dom aktualisiert wird, wenn die Daten einer Komponente geändert wird. Die jQuery muss Höhen von Elementen berechnen, damit ich nicht genau die Daten verwenden kann. Leider sieht es aus wie onAllChangesDone wird nur nach Datenänderungen ausgelöst, nicht das dom.Wie Funktion nach dom Rendern in Angular2

+0

auf diesen [ „Angular 2 mit JQuery“] ähnliche (http://stackoverflow.com/fragen/30623825/how-to-use-jquery-mit-angular2) Problem? Probiere 'setTimeout' aus. – shmck

+0

@shmck, das scheint nur an der Konstruktion zu funktionieren, brauche ich etwas, das es der Funktion erlaubt, jedes Mal zu laufen, wenn die Daten geändert werden und das Dom aktualisiert wird. – ComputerWolf

+1

neue Rückrufe haben in alpha37 https://github.com/angular/angular/blob/2.0.0-alpha.37/CHANGELOG.md Kern hinzugefügt: hinzugefügt afterContentInit, afterViewInit und afterViewChecked Haken (d49bc43) , schließt # 3897 –

Antwort

42

Die einzige Lösung, die ich mit dem Lebenszyklus gefunden habe Haken ngAfterViewChecked.

Beispiel für einen Chat, wo Sie die Nachrichtenliste nach dem Hinzufügen und Rendering eine neue Nachricht blättern haben:

import {Component, AfterViewChecked, ElementRef} from 'angular2/core'; 

@Component({ 
    selector: 'chat', 
    template: ` 
     <div style="max-height:200px; overflow-y:auto;" class="chat-list"> 
      <ul> 
       <li *ngFor="#message of messages;"> 
        {{ message }} 
       </li> 
      </ul> 
     </div> 
     <textarea #txt></textarea> 
     <button (click)="messages.push(txt.value); txt.value = '';">Send</button> 
    ` 
}) 

export class ChatComponent implements AfterViewChecked { 
    public messages: any[] = [];   
    private _prevChatHeight: number = 0; 

    constructor (public element: ElementRef) { 
     this.messages = ['message 3', 'message 2', 'message 1']; 

     this.elChatList = this.element.nativeElement.querySelector('.chat-list'); 
    }  

    public ngAfterViewChecked(): void { 
     /* need _canScrollDown because it triggers even if you enter text in the textarea */ 

     if (this._canScrollDown()) { 
      this.scrollDown(); 
     }  
    }  

    private _canScrollDown(): boolean { 
     /* compares prev and current scrollHeight */ 

     var can = (this._prevChatHeight !== this.elChatList.scrollHeight); 

     this._prevChatHeight = this.elChatList.scrollHeight; 

     return can; 
    } 

    public scrollDown(): void { 
     this.elChatList.scrollTop = this.elChatList.scrollHeight; 
    } 
} 
+3

Verwenden Sie AfterViewChecked nicht, verwenden Sie stattdessen AfterViewInit (nur einmal nach dem ersten AfterViewChecked aufgerufen). https://angular.io/guide/lifecycle-hooks –

+5

@NicoToub AfterViewInit wird manchmal aufgerufen, bevor das DOM erstellt wird. Ich habe mit AfterViewChecked mit manuell gehandhabten Flag gefunden, das Code nur einmal ausführen die einzige Option erlaubt. Es ist nicht elegant, aber es funktioniert. –

Verwandte Themen