【问题标题】:Angular verify value inside an array from the result another array从结果另一个数组中角度验证数组内的值
【发布时间】:2021-03-24 22:17:52
【问题描述】:

我正在尝试从另一个数组的结果中检查一个数组中的一个值,并将一个键放入对象中,以便我可以在我的屏幕上创建一个 ngfor 并带来这些值,但我没有得到它。我需要在服务器数组中创建卷键,getVolumes 端点返回一个包含附件键的对象数组,其中包含 server_id 键,该卷所在的服务器 ID 在哪里。我只需要带上包含 name 键值的卷,但结果是一个空数组。你能帮帮我吗?

我的代码

  ngOnInit(): void {
    forkJoin(this.serverService.getServer(), 
    this.storage.getVolumes())
    .pipe(takeWhile(() => this.alive))
    .subscribe(([servers, volumes]) => {
      this.volumes = volumes;
      this.servers = servers.map((server) => ({
        ...server,
        volumes: this.volumes.map((volume) => {
          volume['attachments'].map((volumeId) => {
            console.log(volumeId)
            volumeId['server_id'] === server.id ? volumeId : 'None';
            console.log(this.servers)
          })
        })
      }))
    })
  }

我的html代码:

<ng-container *ngFor="let volume of volumes">
                <tr *ngIf="volume?.name.length > 2" (click)="selectVolume = volume">
                  <td>  
                    <div class="user-info">
                      <div class="user-info__img">
                        <img src="./assets/img/storages.svg" alt="UserImg">
                      </div>
                      <div class="user-info__basic">
                        <h5 class="mb-0">{{volume.name}}</h5>
                      </div>
                    </div>
                  </td>
                  <td >{{volume.size}} GB</td>

                  <td>
                    <span *ngFor="let attachedVolume of servers.volumes">
                      {{attachedVolume.name}}
                    </span>
                  </td>
</ng-container>

我对 Volume API 的回应:

{
      "id": "939b1432-13f7-41ff-b9d2-908b25499c99",
      "name": "",
      "size": 10,
      "status": "in-use",
      "volume_type": "__DEFAULT__",
      "attachments": [
        {
          "id": "939b1432-13f7-41ff-b9d2-908b25499c99",
          "server_id": "1879f47f-1c5e-464b-bb76-e7cc13ef426e",
          "attachment_id": "5749f842-5dff-48ac-ac57-2a6bfb806ad5",
          "volume_id": "939b1432-13f7-41ff-b9d2-908b25499c99",
          "device": "/dev/vda",
        }
      ]
    },
    {
      "id": "bd91e685-bdd4-4bb8-b25d-18e91f458fb8",
      "name": "Test01",
      "size": 20,
      "status": "in-use",
      "volume_type": "__DEFAULT__",
      "attachments": [
        {
          "id": "bd91e685-bdd4-4bb8-b25d-18e91f458fb8",
          "server_id": "1879f47f-1c5e-464b-bb76-e7cc13ef426e",
          "attachment_id": "f4cd9033-dd6e-4d47-88a7-904c267f162f",
          "volume_id": "bd91e685-bdd4-4bb8-b25d-18e91f458fb8",
          "device": "/dev/vdc"
        }
      ]
    },
    {
      "id": "97b800c5-1061-4a38-b7ec-c4528f248f72",
      "name": "",
      "size": 20,
      "status": "in-use",
      "volume_type": "__DEFAULT__",
      "attachments": [
        {
          "id": "97b800c5-1061-4a38-b7ec-c4528f248f72",
          "server_id": "b9c7e32a-bf99-4250-83cb-13523f9c1604",
          "attachment_id": "c0cd7598-69ba-4ce8-8407-aef68219a00d",
          "volume_id": "97b800c5-1061-4a38-b7ec-c4528f248f72",
          "device": "/dev/vda",
        }
      ]
    },

我的服务器 API 响应

{
      "id": "1879f47f-1c5e-464b-bb76-e7cc13ef426e",
      "name": "olakital",
      "flavor": {
        "id": "21f46a72-7f4f-40c5-9f1f-0100fadbc226",
        "disk": "10",
        "ram": "4000",
        "swap": "",
        "vcpus": "4"
      }
    },
    {
      "id": "b9c7e32a-bf99-4250-83cb-13523f9c1604",
      "name": "teste01",
      "flavor": {
        "id": "59fc4d83-156d-4aa6-84a7-ea1c90d0fde5",
        "disk": "20",
        "ram": "8",
        "swap": "200",
        "vcpus": "4"
      }
    }

【问题讨论】:

    标签: javascript arrays angular ng-bootstrap


    【解决方案1】:

    如果我真的理解您的要求,您可以过滤以 server_id 作为附件的有效卷(名称不为空的卷)。试试这个代码:

    ngOnInit(): void {
        forkJoin(this.serverService.getServer(), 
        this.storage.getVolumes())
        .pipe(takeWhile(() => this.alive))
        .subscribe(([servers, volumes]) => {
          this.volumes = volumes;
          this.servers = servers.map((server) => ({
            ...server,
            volumes: volumes.filter(volume => volume.name && volume.attachments.some(attachment => attachment.server_id == server.id))
    
          }))
        })
      }
    
    HTML: 
    
    <span *ngFor="let server of servers "> 
        <span *ngFor="let attachedVolume of server.volumes "> 
             {{attachedVolume.name}}
        </span>
    </span>
    

    更新: 如果换成这个怎么办?这样就可以直接查看存储分配给哪台服务器了:

    ngOnInit(): void {
        forkJoin(this.serverService.getServer(), 
        this.storage.getVolumes())
        .pipe(takeWhile(() => this.alive))
        .subscribe(([servers, volumes]) => {
          this.volumes = volumes.map(volume => ({
              ...volume,
              servers: servers.filter(server => volume.attachments.some(attachment => attachment.server_id == server.id))
           })),
          this.servers = servers;
        })
      }
    

    HTML:

    <ng-container *ngFor="let volume of volumes">
        <tr *ngIf="volume?.name.length > 2" (click)="selectVolume = volume">
            <td>  
                <div class="user-info">
                    <div class="user-info__img">
                        <img src="./assets/img/storages.svg" alt="UserImg">
                    </div>
                    <div class="user-info__basic">
                        <h5 class="mb-0">{{volume.name}}</h5>
                    </div>
                </div>
            </td>
            <td >{{volume.size}} GB</td>
    
            <td>
                <span *ngFor="let server of volume.servers">
                  {{server.name}}
                </span>
            </td>
    </ng-container>
    

    【讨论】:

    • 我更改了部分代码:volumes: volumes.filter (volume => volume.attachments.some (attachment => attachment.server_id == server.id)) 现在他正在添加它作为我的服务器阵列中的关键卷,但是在我的 HTML 中执行 ngFor 时,他没有绑定,也没有返回错误。它仍然是空的。这是我的 html 代码和服务器阵列日志的图像。服务器数组:imgur.com/a/48sKTBO Html 代码:imgur.com/TCKOxtf
    • 问题是您正试图访问阵列、servers.volumes 上的 voumes 属性,但服务器是一个阵列。您应该首先在服务器属性上进行迭代,然后在卷上进行迭代。我更新我的答案。看看
    • 知道了。我做到了,它确实有效,但我需要的名称是服务器而不是存储。我将代码更改为 volumes: volumes.filter (volume => volume.attachments.some (attachment => attachment.server_id == server.id ? server.name : '')) 它没有用,它仍然是空的,我还是不明白怎么回事。 : /
    • 示例:我有服务器A,它有一个ID为ABC的卷,卷的ABC ID与服务器A的ABC ID相同,所以我需要将server.name放在我的html中显示存储分配给哪台服务器。所以我正在尝试这样做“volume.attachments.some(attachment => attachment.server_id == server.id ? server.name)”
    • 嗨@Dave,我的回答能解决问题吗?
    【解决方案2】:

    试一试,我还没有完全测试过,但是从我收集的内容和您显示的数据来看,似乎当您根据附件中的服务器 ID 过滤卷时,您不返回音量,主要是因为没有返回任何内容,this.servers 中的volumes 属性将是empty arrayundefined

      ngOnInit(): void {
        forkJoin(this.serverService.getServer(), 
        this.storage.getVolumes())
        .pipe(takeWhile(() => this.alive))
        .subscribe(([servers, volumes]) => {
          this.volumes = volumes;
          this.servers = servers.map((server) => ({
            ...server,
            volumes: volumes.reduce((filteredVolumes, volume) => { 
                const found = volume.attachments
                  .filter(attachment => attachment.name && attachment.server_id === server.id);
    
                if(!!found.length) {
                  filteredVolumes.push(volume);
                }
             
                return filteredVolumes;
            }, [])
          }))
        })
      }
    

    【讨论】:

    • 您好,我试过了,它返回错误:/core.js:6241 错误类型错误:result.add is not a function at machine.component.ts:61 at Array.reduce () at machine.component.ts:57 at Array.map () at machine.component.ts:56 at Array.map ()
    • 对不起,我修改了答案,是我错误地写了result.add(...)而不是result.push(...)
    • 嗨,我最终切换到 .push,即使它仍然没有在我的服务器阵列中创建卷键:/图像结果 imgur.com/hytizJ6
    猜你喜欢
    • 2019-04-07
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 2019-01-14
    相关资源
    最近更新 更多