【问题标题】:How to call function after dom renders in Angular2? [duplicate]如何在 Angular2 中渲染 dom 后调用函数? [复制]
【发布时间】:2015-07-01 20:30:49
【问题描述】:

我一般是 Angular2 和 Angular 的新手,我试图在组件的数据更改时更新 dom 后触发一些 jQuery。 jQuery 需要计算元素的高度,所以我不能完全只使用数据。不幸的是,onAllChangesDone 似乎只在数据更改后触发,而不是 dom。

【问题讨论】:

标签: angular


【解决方案1】:

我用生命周期钩子 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;
    }
}

【讨论】:

  • 不要使用 AfterViewChecked,而是使用 AfterViewInit(仅调用一次,在第一个 AfterViewChecked 之后)。 angular.io/guide/lifecycle-hooks
  • @NicoToub AfterViewInit 有时会在 DOM 构建之前被调用。我发现使用带有手动处理标志的 AfterViewChecked 将只允许代码运行一次作为唯一选项。它并不优雅,但很有效。
  • @GeorgeKnap,对不起,我可以请你分享使用 AfterViewChecked 和手动处理标志的代码吗?提前致谢!
  • @lucifer63 你可以有一个条件变量,比如initialViewCheck = false,在ngAfterViewChecked 函数中,你需要编写一个if 条件来评估initialViewCheck 的布尔值。如果是falseif (!this.initialViewCheck)),则在条件内将变量设置为true,并在条件内编写只执行一次的代码。因此,无论何时调用 ngAfterViewChecked,条件都会失败,因为 initialViewCheck 设置为 true
  • 不要使用 AfterViewChecked 。它给我们带来了性能问题,因为它加载被多次触发!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 2019-04-27
  • 2018-06-27
  • 2018-04-05
  • 1970-01-01
相关资源
最近更新 更多