Angular – jak ustawić wartość domyślną dla <select>?

0

Obłaskawiania Angulara ciąg dalszy (po wpisach na mikro). Tym razem chyba nic trudnego, a jednak. Mam prosty element <select>:

Kod online:
https://stackblitz.com/edit/angular-c4hx2v

app.component.html:

<select>
  <option *ngFor="let option of options">
    {{ option }}
  </option>
</select>

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  options = [
    "apple",
    "banana",
    "cucumber"
  ];
}

Chciałbym ustawić wartość domyślną tego elementu <select>. Gdyby elementy <option> nie były generowane za pomocą pętli, to ustawiłbym atrybut selected na którymś z nich.


PS. Jeśli jest kilka możliwych rozwiązań, prosiłbym o pokazanie najprostszego i najbardziej "angularowego".


UPDATE: Wybaczcie, że link do StackBlitz posiada cokolwiek nieaktualny kod, ale coś mi StackBlitz nie chce działać, jak ja chcę. Nie mam ochoty (teraz) dochodzić, czemu.

1
<option *ngFor="let option of options" [selected]="option.selected">
      {{ option.value }}
    </option>

options = [
    {
      value: 'Jabłko',
      selected: false
    },
    {
      value: 'Pomidor',
      selected: true
    }
]
    
0

OK, dzięki, @froziu, to wygląda sensownie. Będę musiał poczytać w takim razie o tych nawiasach prostokątnych.

Ale nie jestem pewien, jak to rozwiązanie wykorzystać dla mojego przypadku użycia. Docelowo przechowuję indeks w zmiennej (obiekt jest bardziej złożony, ale to nie ma znaczenia), powiedzmy: const initialSelectedIndex = 2, a nie mam wartości true/false. Żeby wykorzystać Twoje rozwiązanie, musiałbym mapować powyższe options na przykład w taki sposób:

options.map((e, i) => { return { name: e, selected: i === initialSelectedIndex } });

I to mapowanie umieszczam w pliku app.component.ts. I to działa. Tutaj jak to zrobiłem:

app.component.html:

<select>
  <option *ngFor="let option of mappedOptions" [selected]="option.selected">
    {{ option.name }}
  </option>
</select>

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  options = [
    "apple",
    "banana",
    "cucumber"
  ];
  initialSelectedIndex = 2;
  mappedOptions = this.options.map((e, i) => { return { name: e, selected: i === this.initialSelectedIndex } });
}

Ale miałbym dwa pytania:

  1. Dlaczego zmienna option istnieje w [selected]? Przecież została zdefiniowana w *ngfor.
  2. Czy można jakoś ładniej to zrobić? Tworzenie dodatkowego pola klasy komponentu (jak ja zrobiłem) nie wydaje mi się odpowiednie w tym przypadku, tym bardziej umieszczanie mapowania bezpośrednio w *ngFor...

UPDATE:

Poczytałem sobie o property binding w Angularze i teraz tak zrobiłem:

app.component.html:

<select>
  <option *ngFor="let option of options" [selected]="initialSelectedIndex">
    {{ option }}
  </option>
</select>

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  options = [
    "apple",
    "banana",
    "cucumber"
  ];
  initialSelectedIndex = 2;
}

Jakkolwiek moje powyższe dwa pytania pozostają aktualne, to chyba obecnie to mi wystarczy w praktyce (skoro działa).


UPDATE: W zasadzie jedno pytanie, to o działanie zmiennej option; powyższy mój sposób jest już "wystarczająco-ładniejszy" od poprzedniego.

1

Szczerze nie jestem na tyle zaawansowany aby dać Ci odpowiedź czy jest to optymalne rozwiązanie.
Co do widoczności, wydaje mi się że zmienna option jest widoczna w ramach całego elementu option (docelowo tworzy się ich tyle ile wynosi wielkość Twojej tablicy).
Możesz to wykorzystać w różny sposób np. możesz bindować właściwości elementu dodając klasy, style itd.
np.

<button *ngFor="let button of buttons" class="{{button.class}}> {{button.name}} </button>

mając tablicę buttonów np.

let buttons = [{ name: 'Dodaj', class: 'btn-success'},{ name: 'Usuń', class: 'btn-danger'}]

.

W praktyce możesz jeszcze ogarnąć coś takiego

<option *ngFor="let option of options; let i = index" [selected]="i === initialSelectedIndex"> 

wykorzystując index elementów.

EDIT.

https://malcoded.com/posts/angular-ngfor/ . Ogólnie polecam całe, ale Ciebie chyba interesuje 'Variable Scope'

0

Dziękuję za spojrzenie i wskazówki. Każda się przyda, choć te mniej związane z bieżącymi problemami staram się omijać, odkładając na później, gdy będę mieć więcej czasu. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1