Angular - отображать любые json данные в представлении компонента представления в al oop без знания структуры - PullRequest
0 голосов
/ 09 июля 2020

У меня есть json данных, которые мне нужно отобразить в моем app.component. html

Вот несколько примеров данных:

[
  {
    "name": "d1",
    "days": [
      "monday",
      "wednesday",
    ],
    "options": {
      "name": "o1",
      "extras": [],
      "temp": [
        "12",
        "25",
        "12"
      ]
    }
  },
  {
    "name": "d2",
    "days": [
      "tuesday",
      "wednesday",
    ],
    "options": {
      "name": "o2a",
      "extras": [
        {
          name: 'extra 1'
        }
      ],
      "temp": [
        "22",
        "25",
        "12"
      ]
    }
  }
]

На данный момент у меня есть это так:

<ul *ngFor="let dat of data">
  <li>{{dat.name}}</li>
</ul>

.. et c

Но имена и значения ключей не фиксированы, поэтому они могут меняться и быть более или менее.

У меня вопрос, как я могу это сделать, если он может читать любые json данные?

Ответы [ 3 ]

2 голосов
/ 09 июля 2020

Вы пишете <li>{{dat.name}}</li> и ожидаете, что все будет работать, если ключ name будет изменен, тогда это невозможно.

Однако, если вы просто хотите отобразить весь JSON в своем пользовательском интерфейсе , вы можете использовать канал json, например ::

<li>{{dat | json}}</li>

Если вы хотите, чтобы JSON отображался в удобном печатном формате, измените его на ::

<code><div *ngFor="let dat of data">
    <pre>{{dat | json}}
0 голосов
/ 09 июля 2020

Вероятно, есть более приятный Angular или JS JSON Tree viewer, но с него можно начать. Вам нужно рекурсивно перебирать ваши объекты.

Я использую здесь рекурсивные выходы шаблонов, вы можете создавать компоненты (и если вам нужно добавить другие функции, возможно, стоит изучить это).

Вот демонстрация блиц-теста стека: https://stackblitz.com/edit/angular-ivy-qadvlr?file=src%2Fapp%2Fapp.component.ts

Пример компонента, он просто содержит ваши данные в виде массива и вспомогательный метод, чтобы попытаться определить тип значения мы были переданы, так как его тип будет определять, как нам его отображать.

export class AppComponent  {
  data1 = [
    {
      "name": "d1",
      "days": [
        "monday",
        "wednesday",
      ],
      "options": {
        "name": "o1",
        "extras": [],
        "temp": [
          "12",
          "25",
          "12"
        ]
      }
    },
    {
      "name": "d2",
      "days": [
        "tuesday",
        "wednesday",
      ],
      "options": {
        "name": "o2a",
        "extras": [
          {
            name: 'extra 1'
          }
        ],
        "temp": [
          "22",
          "25",
          "12"
        ]
      }
    }
  ]

  getType(val: any) {
    if (Array.isArray(val)) {// aray's will be type of "object" so need specail cases, and possibly others but this is a good start
      return 'array';
    } else if (typeof val === 'string' || val instanceof String) {
      return 'string';
    } else if (typeof val === 'boolean') {
      return 'boolean';
    } else if (typeof val === "object") {
      return 'object'
    }
  }

}

Довольно беспорядочные рекурсивные шаблоны, которые не заботятся об именах свойств. Вместо этого мы используем канал Angular keyvalue для получения ключей / значений объекта.

<ul *ngFor="let someObj of data1;">
  <ng-container *ngTemplateOutlet="objectTemplate; context: {obj: someObj}"></ng-container>
</ul>


<ng-template #recursiveTemplate let-key="key" let-valueType="valueType" let-value="value">
  {{key}}

  <ng-container [ngSwitch]="valueType">

      <ng-container *ngSwitchCase="'array'">
        <ng-container *ngTemplateOutlet="arrayTemplate; context: { value: value}"></ng-container>
      </ng-container>

      <ng-container *ngSwitchCase="'object'">
        <ul>
        <ng-container *ngTemplateOutlet="objectTemplate; context: {obj: value}"></ng-container>
        </ul>
      </ng-container>

      <!-- anything we might have missed or don't needs anything special for, just show it as JSON -->
      <ng-container *ngSwitchDefault>
         {{key ? "- " : ""}}{{value | json}}
      </ng-container>

  </ng-container>
</ng-template>

<ng-template #arrayTemplate let-value="value">
  <ul>
    <li *ngFor="let child of value;">
        <ng-container *ngTemplateOutlet="recursiveTemplate; context:{ key:null, valueType: getType(child), value: child }"></ng-container>
    </li>
  </ul>
</ng-template>

<ng-template #objectTemplate let-obj="obj">
  <li *ngFor="let item of obj | keyvalue;">
  <ng-container *ngTemplateOutlet="recursiveTemplate; context:{ key:item.key, valueType: getType(item.value), value: item.value }"></ng-container>
  </li>
</ng-template>
0 голосов
/ 09 июля 2020

Просто сделайте это.

<code><pre>
{{ data | json }}
...