AfterViewInit 调用得太早了吗?

AfterViewInit is called too early?

我正在使用 Angular 5.2.1 开发一个 angular 网站。我创建了一个在一个视图中多次使用的组件。要访问它,请在该组件的构造函数中为该组件创建一个唯一的 ID。

AfterViewInit 活动中我想订阅一个活动。但似乎在 AfterViewInit 被解雇后不久该组件仍然不可用。

HTML

<a data-toggle="collapse" href="#{{componentId}}">Toggle</a>

<div id="{{componentId}}" class="collapse">
    <!-- tabset content -->
</div>

组件

declare var $: any

@Component({
    selector: 'my-component',
    templateUrl: './my-component.component.html'
})

export class MyComponentComponent implements OnInit, AfterViewInit {
    // Some inputs

    public componentId: string
    // Some other component variables

    constructor(
        private generatorService: GeneratorService
    ) {
        // Generate unique Id for the component, length 10
        this.componentId = this.generatorService.generateId(10)
    }

    ngOnInit() {
    }

    ngAfterViewInit(): void {
        console.log(this.componentId) // Correct id is printed to console
        console.log($('#' + this.componentId)) // Returning empty result

        // So this is not working:
        $('#' + this.componentId).on('hide.bs.collapse', () => {
            // Do something
        })
    }

    // Some other code
}

据我所知,AfterViewInit 通常在组件完全初始化并添加到 DOM 时触发。当我稍等片刻并手动写入 $('#[myComponentId]') 以控制台时,我得到了正确的结果。

我做错了什么?

好的,我刚找到一个肮脏的解决方法。

我写了一个递归方法,最初在 AfterViewInit 方法中调用。

我的组件现在如下所示

declare var $: any

@Component({
    selector: 'my-component',
    templateUrl: './my-component.component.html'
})

export class MyComponentComponent implements OnInit, AfterViewInit {
    // Some inputs

    public componentId: string
    // Some other component variables

    private iteration: number = 0

    constructor(
        private generatorService: GeneratorService
    ) {
        // Generate unique Id for the component, length 10
        this.componentId = this.generatorService.generateId(10)
    }

    ngOnInit() {
    }

    ngAfterViewInit(): void {
        console.log(this.componentId) // Correct id is printed to console

        this.registerEvents()
    }

    registerEvents() {
        setTimeout(() => {
            if (!('#' + this.componentId)[0]) {
                this.iteration++
                this.registerEvents()
                return
            }

            console.log(this.iteration) // Prints a value between 3 and 5
            $('#' + this.componentId).on('hide.bs.collapse', () => {
                // Do something
            })
        }, this.iteration * 10)
    }

    // Some other code
}

我不知道为什么会这样,但现在我又可以工作了。