【问题标题】:Angular Material matToolTip does not display when using ngFor function使用 ngFor 函数时不显示 Angular Material matToolTip
【发布时间】:2018-04-03 15:07:46
【问题描述】:

我有一组称为报告的数据,其中包含一组网络 (report.networks)。在我返回之前,我有 model.ts 来操作网络数组。我做了一个 ngFor 来遍历网络数据以显示工作正常的细节。但是,在 ngFor 中添加 matToolTips 不会显示。

component.html

<span matTooltip="Tooltip Works">Tooltip Works</span>

<div *ngFor="let network of report.networks">
   <span matTooltip="Tooltip Does NOT work!">Tooltip Does NOT work</span>
</div>

component.ts

import { Report } from './../../core/models/report/report.model';

@Component({
    selector: 'app-report-detail',
    templateUrl: './report-detail.component.html',
    styleUrls: ['./report-detail.component.scss']
})
export class ReportDetailComponent implements OnInit {

    report: Report;

    constructor(private route: ActivatedRoute) { }

    ngOnInit() {

        this.report = this.route.snapshot.data.report;
        console.log(this.report);

    }

}

report.model.ts

export class Report {

    networks?: any = null;

    constructor(data?: Report) {
        if (data) {
            this.deserialize(data);
        }
    }

    private deserialize(data: Report) {

        const keys = Object.keys(this);

        for (const key of keys) {
            if (data.hasOwnProperty(key)) {
                this[key] = data[key];
            }
        }
    }

    get networks() {

        let n = this.networks;
        //some manipulation
        return n
    }
}

【问题讨论】:

  • 你能检查你的控制台是否有关于你的 ngFor 的错误,因为它似乎在这里工作得很好stackblitz.com/edit/angular-dsm5ks
  • @PierreMallet 控制台中没有错误但显然 report.networks 是一个函数,这就是为什么它不起作用检查 github.com/angular/material2/issues/10039 但我不知道这一点,因为报告来自我调用的 model.ts 文件数据数组。
  • 我经常这样做,因为我需要在返回数据之前对其进行操作,我在模型文件中完成所有这些。

标签: angular angular-material


【解决方案1】:

由于您的网络 getter 每次都返回一个新集合,因此工具提示总是在 ngFor 在 DOM 中重新创建新元素时重新关闭。

但是,如果您在返回的网络中有标识符,则可以解决此问题。

ngFor* 指令接受一个 trackBy 函数,该函数将用于检查现有渲染项目与必须显示的项目的身份。如果此函数返回的值对于现有项和要创建的项相同,则 Angular 将保留现有项,因此不会破坏它。

这里是指南中的an exemple,以及the internal mechanism 和TrackByFn interface 的文档

    in the template : 

    <div *ngFor="let network of networks(); trackBy: trackByFn">
       <span matTooltip="Tooltip Does NOT work!">Tooltip Does NOT work</span>
    </div>
    ...
    In the component: 

    networks () { let n = [{ name: 'toto', id: 1},{ id: 2 } , { id: 3 } ]; return n;  };
    trackByFn = (index: number, item: any) => item.id;

这里是stackblitz实现了一个简单的trackByFunction,你可以看到使用trackBy的工具提示

编辑:如果你没有任何 id,你可以使用你的数组的索引,ergo:

trackByFn = (index: number, item: any) => index;

【讨论】:

  • 我没有每次都有特定的 id,但是如果它是一个数组,我可以不只使用索引吗?
【解决方案2】:

这里提到https://github.com/angular/material2/issues/10039

在 ngFor 中使用函数时会一遍又一遍地创建数组实例,这会导致 matToolTip 无法显示等多个问题以及性能问题。

我解决这个问题的另一种方法是更改​​我的 model.ts 文件。所以下面我将一个变量分配给函数的结果。然后我在函数的 ngFor 中直接使用这个变量。

export class Report {

    networks?: any = null;

    //custom

    customNetworks? : any = null;

    constructor(data?: Report) {
        if (data) {
            this.deserialize(data);

            this.customNetworks = this.generateNetworks()
        }

    }

    private deserialize(data: Report) {

        const keys = Object.keys(this);

        for (const key of keys) {
            if (data.hasOwnProperty(key)) {
                this[key] = data[key];
            }
        }
    }

    generateNetworks() {

        let n = this.networks;
        //some manipulation
        return n
    }
}

【讨论】:

    猜你喜欢
    • 2019-10-20
    • 2020-12-03
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    相关资源
    最近更新 更多