如何在Angular2中进行dom渲染后调用函数?

Com*_*olf 41 angular

我一般都是Angular2和Angular的新手,并且在组件的数据发生更改后更新dom后尝试获取一些jQuery.jQuery需要计算元素的高度,所以我不能完全使用数据.不幸的是,看起来onAllChangesDone只在数据更改后触发,而不是dom.

Art*_*tod 60

我发现生命周期钩子ngAfterViewChecked的唯一解决方案.

聊天示例,您必须在添加和呈现新消息后向下滚动消息列表:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @NicoToub AfterViewInit有时会在构造DOM之前被调用.我发现使用带有手动处理标志的AfterViewChecked将允许代码只运行一次唯一选项.它不优雅,但它的工作原理. (19认同)
  • 不要使用AfterViewChecked,而是使用AfterViewInit(仅在第一次AfterViewChecked之后调用一次).https://angular.io/guide/lifecycle-hooks (7认同)
  • @ lucifer63你可以有一个条件变量,比如`initialViewCheck = false`,在`ngAfterViewChecked`函数中,你需要写一个`if`条件来评估`initialViewCheck`的布尔值.如果它是`false`(`if(!this.initialViewCheck)`),则在条件内将变量设置为"true",并将代码写入您只想执行一次的条件.因此,每当调用`ngAfterViewChecked`时,条件就会失败,因为`initialViewCheck`设置为'true`. (4认同)