Angular ngFor - 在 ts 中得到一个 属性

Angular ngFor - get a property in ts

我需要一些帮助...

我正在用 angular 和 material 制作一个聊天应用程序,我只需要在下一条用户消息输入之前显示一次用户昵称(比如 whatsapp 或类似的东西)像这样:

用户 1: 消息 1 消息 2 留言 3 用户 2: 消息 1 消息 2 用户 1: 消息 4 等等

这是我的 component.ts:

  messages: any[] = [
    {
      nickname: 'user1',
      msg: 'hola que tal 1',
      img: "https://images-na.ssl-images-amazon.com/images/I/81PohdE46lL.jpg"
    },
    {
      nickname: 'user1',
      msg: 'hola que tal 2',
      img: "https://images-na.ssl-images-amazon.com/images/I/81PohdE46lL.jpg"
    },
    {
      nickname: 'user1',
      msg: 'hola que tal 3',
      img: "https://images-na.ssl-images-amazon.com/images/I/81PohdE46lL.jpg"
    },
    {
      nickname: 'user2',
      msg: 'hola que tal 4',
      img: "https://images-na.ssl-images-amazon.com/images/I/81PohdE46lL.jpg"
    },
    {
      nickname: 'user2',
      msg: 'hola que tal 4',
      img: "https://images-na.ssl-images-amazon.com/images/I/81PohdE46lL.jpg"
    },
  ];

username: string = "test";
temp_user: string = "";

changeTemp(nickname: string): void {
    this.temp_user = nickname;
  }

这是我的 HTML 我实现的(丑陋的)解决方案:

            <mat-card-content>
                <div class="chat-window" #chat_window>
                    <mat-list role="list">
                        <div *ngFor="let msg of messages">
                            <div *ngIf="temp_user !== msg.nickname" class="avatar"
                                [ngClass]="{ 'right-avatar': msg.nickname == username}">
                                <!-- <img class="avatar-img" [src]="msg.img" alt="..."> -->
                                {{ msg.nickname }}
                                {{ changeTemp(msg.nickname) }}
                            </div>
                            <mat-list-item class="chat-message" role="listitem"
                                [ngClass]="{ 'right-message': msg.nickname == username}">
                                {{ msg.msg }}
                            </mat-list-item>
                        </div>
                    </mat-list>
                </div>
            </mat-card-content>

这是结果: result 我用字符串插值调用了 changeTemp() 函数来保存临时用户,并检查它是否在下一个用户消息之前用 ngIf 重复,但这(在这种情况下调用函数)对我来说听起来不是一个好习惯...

有解决这个问题的干净方法吗?以某种方式或替代方式获得临时用户?我已经尝试使用发出事件的指令和 trackBy 解决方案,但在这种情况下效果不佳。

非常感谢。

在将列表交给 HTML 完成其工作之前,您可以按更方便的顺序对列表进行分组。

假设你的数组是,

var arr = [
  {tag: 'one', content: 'A'},
  {tag: 'one', content: 'B'},
  {tag: 'two', content: 'C'},
  {tag: 'two', content: 'D'},
  {tag: 'three', content: 'E'},
  {tag: 'three', content: 'F'}
];

方便下单,

{
      one: [
        {tag: 'one', content: 'A'},
        {tag: 'one', content: 'B'}
      ],
      two: [
        {tag: 'two', content: 'C'},
        {tag: 'two', content: 'D'}
      ],
      three: [
        {tag: 'three', content: 'E'},
        {tag: 'three', content: 'F'}
      ]
    }

您可以使用“group-array”包或手动对数组进行分组。如果你想使用“group-array”包,下面我已经提到了 link 和一个从原始文档复制的示例来对数组进行分组。 Link : https://www.npmjs.com/package/group-array#examples

//npm i group-array
// group by the `tag` property
   groupArray(arr, 'tag');

在你的HTML

<div *ngFor="let item of yourList | keyvalue">
   <div >
       Message From - {{item.key}}
   </div>
   <div>
       <p  *ngFor="let message of item.value">
            {{message.content}}
       </p>
   </div>
 </div>

输出:

Message From - one
A
B

Message From - three
E
F

Message From - two
C
D