【问题标题】:Iterating Values in Angular 9 from LocalStorage从 LocalStorage 迭代 Angular 9 中的值
【发布时间】:2020-08-26 16:56:30
【问题描述】:

我在 Angular 中显示来自 Localstorage 的嵌套值时遇到问题。问题出在第二个 *ngFor 上。第一个 *ngFor 显示良好。第二个 ngFor 出现“TypeError: Cannot read property 'toUpperCase' of undefined”的错误?我不知道为什么是 toUppercase,因为我在这里没有使用大写

HTML

<mat-list-item role="listitem" *ngFor="let bookmark of bookmarks">
     {{ extractNameFromJson(bookmark[1]).id }}
         <ul>
           <li *ngFor="let extractNameFromJson(bookmark[1])?.cuesData of bookmark">
                   {{ }}   
            </li>
         </ul>
 </mat-list-item>

TS

 getAllBookmarks() {
   this.bookmarks = Object.entries(localStorage);
   console.log(this.bookmarks);
 }

 extractNameFromJson(obj) {
    obj = JSON.parse(obj);
    return obj;
  }

【问题讨论】:

  • bookmark的数据结构是什么?
  • @T.SunilRao。请检查已编辑的帖子

标签: angular angular6 angular7 angular-forms angular-ngfor


【解决方案1】:

您需要先将每个 bookMark 的值作为变量获取到 *ngFor 中。使用ngFor 从循环中提取变量时不能调用函数。一种方法是让pipe 在循环时为您执行此过滤,或者另一种方法是使用ng-container 循环并仅在您的条件通过时显示lis

<ng-container *ngFor="let eachBookMark of bookmark">
    <ng-container *ngIf="extractNameFromJson(eachBookMark[1]) as data">
        <ng-container *ngIf="data.cuesData">
            <li *ngFor="data.cuesData">
                {{data | json}}
            </li>
        </ng-container>
    </ng-container>
</ng-container>

编辑: 如果你想更改 ts 中的 bookmarks 数组,也许你可以这样做:

this.bookmarks = this.bookmarks.map(([first, second]) => {
    return [first, JSON.parse(second)];
});

现在,如果你已经这样做了,那么你的 HTML 可以很简单:

<mat-list-item role="listitem" *ngFor="let eachBookMark of bookmarks">
    <ul>
        <ng-container *ngIf="eachBookMark[1].cuesData as cuesData">
            <li *ngFor="let eachCue of cuesData">
                {{ eachCue.description }}   
            </li>
        </ng-container>
    </ul>
</mat-list-item>

EDIT2:

this.filteredBookmarks = this.bookmarks.reduce((acc, [first, second]) => {
    const parsedOb = JSON.parse(second);
    if (parsedOb.cuesData) {
        acc.push([first, parsedOb]);
    }
    return acc;
}, []);

<mat-list-item role="listitem" *ngFor="let eachBookMark of filteredBookmarks">
    <ul>
        <li *ngFor="let eachCue of cuesData">
                {{ eachCue.description }}   
        </li>
    </ul>
</mat-list-item>

上述所有过滤(map/reduce)将发生在您填充bookmarks的地方。

【讨论】:

  • 谢谢。你能帮我把它转换成 TS 文件吗?所以我不会在 HTML 中做这个 extractNameFromJson() 函数。谢谢
  • @Joseph 如果要将第二个元素转换为 ts 中的对象并将其存储在同一个数组中,则可以使用更新。如果你想维护一个不同的数组来维护转换后的对象,你也可以这样做。
  • 可以改写成TS吗?请同时修改您的 HTML。只需在此处编辑您的答案。谢谢
  • @Joseph Done,添加了一种方法。另一种方法是在 ts 中使用Array.filter(),而不是map,并且只返回具有cuesData 的数组,这不需要在ng-container 中进行额外检查。这取决于您对自己的应用的感觉。
  • @Joseph 完成最后的编辑,我想你可以从这里开始。
【解决方案2】:

按要求更新

TS:

 getAllBookmarks() {
   this.bookmarks = this.extractNameFromJson(Object.entries(localStorage));
   console.log(this.bookmarks);
 }

 extractNameFromJson(obj) {
   obj = JSON.parse(obj);
   return obj;
 }

HTML:

<mat-list-item role="listitem" *ngFor="let bookmark of bookmarks">
  {{ bookmark[1].id }}
  <ul *ngIf="bookmark[1].cuesData>
    <li *ngFor="let cue of bookmark[1].cuesData">
      {{ cue.description }}   
    </li>
  </ul>
</mat-list-item>

原答案

第二个*ngFor语法不正确

根据您发布的内容推断,这就是您所需要的。

更新:新增功能extractNameFromJson

     <ul *ngIf="bookmark[1].cuesData">
       <li *ngFor="let cue of extractNameFromJson(bookmark[1].cuesData)">
         {{ cue.description }}   
       </li>
     </ul>

假设您需要在屏幕截图中显示description,您也可以显示startTimeendTime

希望对你有帮助!

【讨论】:

  • 我想你忘记输入 extractNameFromJson() 了?它没有显示。顺便问一下,你能帮我把它转换成 TS 文件吗?所以我不会在 HTML 中做这个 extractNameFromJson() 函数。谢谢
  • 新增功能extractNameFromJson()
  • 在 TS 中转换会更好。
  • 请将其转换为 TS。您的 html 此处未显示。
  • 现在检查整个事情。
猜你喜欢
  • 1970-01-01
  • 2021-06-06
  • 2020-09-24
  • 2020-09-03
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-22
相关资源
最近更新 更多