代码之家  ›  专栏  ›  技术社区  ›  Bob Ramsey

需要关于延迟加载mat手风琴内容的帮助

  •  6
  • Bob Ramsey  · 技术社区  · 6 年前

    我用Angular 5和mat accordion显示作者列表。每个作者都写过多本书和多篇文章。作者姓名显示在面板标题中,面板内容显示所有书籍、文章等。

    因为我想显示100多名作者,每个作者有50多个条目,所以我不想一次填充整个手风琴和内容。我希望发生的是,当用户单击作者时,它会启动一个查询数据库的服务,然后根据需要填充面板内容。如果面板关闭,内容应保持不变,以便重新扩展面板不会启动另一个数据库查询。

    因此,当我访问该页面时,我看到了作者Alice、Bob和Eve。当点击Alice时,应用程序查询数据库,获取Alice的条目,呈现内容,然后手风琴展开。当我点击Eve时,应用程序应该关闭Alice的面板,查询db,获取Eve的条目,呈现内容,最后展开面板。

    如果我再次单击Alice,Eve的面板将关闭,但由于Alice的内容已经存在,因此没有db查询或渲染。它只是膨胀。文档中说要使用ng模板,但我不知道怎么做,也不知道怎么做,所以面板关闭后内容仍然保留。我并不担心数据会发生变化,如果发生变化,需要再次获取Alice的数据。

    有没有最好的处理方法的例子?

    谢谢

    G、 特兰特的回答是正确的,我走的是正确的道路。如果还有其他人出现在这一页上,下面是我最后做的事情。

    ngOnInit(){ 
        this.authorsRetrieved.subscribe( authors => {
            this.allAuthors = authors as Array;
            this.authorsRetrieved = new Array(
                Math.max.apply(Math, this.allTrainers.map(function(t){ return t.trainer_id; }))
            );
    // as authors are added and deleted, the author_id won't equal the number of 
    // authors, so get the highest id number, create an array that long
    // then fill it with blanks so the keys have some value
                this.authorsRetrieved.fill([{}]);
            });
    

    showAuthorsWorks(authorID: Number = -1){
        if(authorID > this.authorsRetrieved.length){
          const tempArray = new Array(authorID - this.authorsRetrieved.length + 1);
          tempArray.fill([{}]);
          this.authorsRetrieved = this.authorsRetrieved.concat(tempArray);
        }
    // only make the network call if we have to
    // because we filled the id array, we can't just use length
    if(typeof(this.authorsRetrieved[authorID][0]['manuscript_id']) === 'undefined'){
      this.authorWorksService.getAuthorWorks(authorID).subscribe( works => {
        this.worksRetrieved.splice(authorID, 0, works as Array<any>);
      });
    }
    

    我添加了一个检查,用于检查数组长度小于最大author\u id的几乎不可能的情况。您必须创建一个包含N个元素的空数组,然后填充该数组。否则,空数组的长度为0,并且不能将数据推送到不存在的数组元素。尽管在chrome控制台上显示长度为N,元素在那里,只是空的。

    再次感谢!

    1 回复  |  直到 6 年前
        1
  •  4
  •   G. Tranter    6 年前

    如果您引用的是与ng模板一起使用的MatExpansionPanelContent指令,那么所做的就是延迟加载内容,直到面板打开为止。它不知道是否已经加载。因此,如果您对{{lazyContent}}等内容使用绑定表达式,则每次打开选项卡时都会对其求值。您需要自己管理内容缓存。一个简单的方法是通过getter。

    在您的组件中:

    _lazyContent: string;
    get lazyContent() {
        if (!this._lazyContent) {
            this._lazyContent = fetchContent();
        }
        return this._lazyContent;
    }
    

    在HTML中添加:

    <mat-expansion-panel>
        ...
        <ng-template matExpansionPanelContent>
            {{lazyContent}}
        </ng-template>
        ....
    </mat-expansion-panel>
    

    因此,ng模板负责延迟加载,getter负责缓存内容。