Как перебрать массив JSON в angular - PullRequest
0 голосов
/ 26 апреля 2020

В моем приложении angular я использую API для получения данных о выбранной стране.

Я не могу заставить мое приложение отображать свойство name из раздела языков в данных ответа, которое выглядит следующим образом:

[{
    "name": "Colombia",
    "topLevelDomain": [".co"],
    "alpha2Code": "CO",
    "alpha3Code": "COL",
    "callingCodes": ["57"],
    "capital": "Bogotá",
    "altSpellings": ["CO", "Republic of Colombia", "República de Colombia"],
    "region": "Americas",
    "subregion": "South America",
    "population": 48759958,
    "latlng": [4.0, -72.0],
    "demonym": "Colombian",
    "area": 1141748.0,
    "gini": 55.9,
    "timezones": ["UTC-05:00"],
    "borders": ["BRA", "ECU", "PAN", "PER", "VEN"],
    "nativeName": "Colombia",
    "numericCode": "170",
    "currencies": [{
        "code": "COP",
        "name": "Colombian peso",
        "symbol": "$"
    }],
    "languages": [{
        "iso639_1": "es",
        "iso639_2": "spa",
        "name": "Spanish",
        "nativeName": "Español"
    }],
    "translations": {
        "de": "Kolumbien",
        "es": "Colombia",
        "fr": "Colombie",
        "ja": "コロンビア",
        "it": "Colombia",
        "br": "Colômbia",
        "pt": "Colômbia"
    },
    "flag": "https://restcountries.eu/data/col.svg",
    "regionalBlocs": [{
        "acronym": "PA",
        "name": "Pacific Alliance",
        "otherAcronyms": [],
        "otherNames": ["Alianza del Pacífico"]
    }, {
        "acronym": "USAN",
        "name": "Union of South American Nations",
        "otherAcronyms": ["UNASUR", "UNASUL", "UZAN"],
        "otherNames": ["Unión de Naciones Suramericanas", "União de Nações Sul-Americanas", "Unie van Zuid-Amerikaanse Naties", "South American Union"]
    }],
    "cioc": "COL"
}]

Я пытался использовать каналы, вложенные * ngFor Циклы, но не повезло в отображении названия языка. Любые предложения?

В моем шаблоне я использую следующие HTML и интерполяцию для отображения имени объекта страны: Как использовать аналогичный подход для доступа к свойству name на языках данных ответа?

             <div>
                <label>Country Capital:</label>
                <p>{{ country.capital }} </p>
            </div>

Мое приложение состоит из 3 модулей, 1 родительского (CountryComponent) и двух дочерних компонентов (CountryListComponent) и (CountryDetailComponent). Данные отправляются из компонента List в компонент Detail с помощью eventEmmiter. Я использую следующую модель для типа «Страна»:

 export interface Country {

      name: string;
topLevelDomain?: string[];
alpha2Code?: string;
alpha3Code?: string;
callingCodes?: string[];
capital?: string;
altSpellings?: string[];
region?: string;
subregion?: string;
population?: number;
latlng?: number[];
demonym?: string;
area?: number;
gini?: number;
timezones?: string[];
borders?: string[];
nativeName?: string;
numericCode?: string;
currencies?: Currency[];
languages?: Language[];
translations?: Translation;
flag?: string;
regionalBlocs?: Regional[];
cioc?: string;

}

В своем компоненте списка я использую следующее для извлечения данных с использованием класса обслуживания и инициализации массива стран типа «Страна» и использования eventEmmiter для выдачи объект страны для компонента Detail:

 public countries: Country[];
  getCountries(){
    this.countryService
      .getCountries()
      .subscribe((data: any) => {
        this.countries = data;
      },
      error => {console.log('error loading')});
  }
  @Output() selectedCountry = new EventEmitter<Country>();

Шаблон компонента списка:

<li class="list-group-item" 
            highlightDirective 
            style="cursor: pointer;
                text-align: center;
                font-family:'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;"
            *ngFor="let country of countries | searchFilter: searchText : 'name'" (click)="onCountrySelected(country)">
            {{ country.name }}
        </li>

В компоненте Detail я получаю событие:

@Input() country: Country;

И в шаблоне Detail я пытаюсь отобразить его:

    <h2> {{ country.name }} </h2>
        <br>
        <div class="row" #countrySelected>
            <div class="col-sm">
                <label>Country Capital:</label>
                <p>{{ country.capital }} </p>
                <p>{{ country.languages.name }}</p>
            </div>
            <div>

Я использую eventEmmiter для отправки объекта страны из компонента List в компонент Detail, используя родительский компонент, родительский шаблон выглядит следующим образом:

<div class="row"
style="padding-left: 20px;
        padding-right: 20px;">
    <div class="col-xs-5">
        <app-country-list (selectedCountry)="childEventClicked($event)"></app-country-list>
    </div>
    <div class="col-xs-7">
        <app-country-detail [country]="(selectedCountryEvent)"></app-country-detail>
    </div>
</div>

1 Ответ

0 голосов
/ 26 апреля 2020

Учитывая, что каждый объект содержится в массиве, я предполагаю, что каждое свойство может содержать более одного объекта в качестве значений. Вы можете попробовать следующее.

Я назначаю ответ от API для переменной с именем countries.

Контроллер

countries = [];

getData() {
  this.apiService.getCountries().subscribe(
    response => { this.countries = response; },
    error => { // handle error }
  );
}

Шаблон

<div *ngFor="let country of countries">
  <label>Country Capital:</label>
  <p>{{ country.capital }} </p>
  <label>Languages:</label>
  <p *ngFor="let language of country.languages">{{ language.name }}</p>
  <label>Currencies:</label>
  <p *ngFor="let currency of country.currencies">{{ currency.name }}</p>
</div>

Обновление

Существует проблема с определением интерфейса. Свойство languages определяется как массив типа string, тогда как это пользовательский объект. Вы можете определить отдельный интерфейс для каждого типа объекта. Попробуйте следующее

export interface Country {
  name: string;
  topLevelDomain?: string[];
  alpha2Code?: string;
  languages?: Language[];
  currencies?: Currency[];
  translations?: Translate[];
  regionalBlocs?: RegionalBloc[];
  .
  .
  .
}

export interface Language {
  iso639_1:? string;
  iso639_2:? string;
  name:? string;
  nativeName:? string;
}

И то же самое относится и к другим свойствам currencies, translations и regionalBlocs. Каждому нужны свои собственные определения интерфейса, аналогичные приведенным здесь для languages.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...