To drugi zbiór swobodnych doświadczeń z Angularem 6. Tutaj jest pierwszy.
Tylko przystąpiłem do kolejnej sesji zapoznawczej, a tu:
Uncaught Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input'.
Rozwiązaniem tego problemu okazało się zaimportowanie kolejnego modułu do mojej aplikacji
import { FormsModule } from '@angular/forms'; @NgModule({ declarations: [ AppComponent, QuizListComponent, QuizComponent ], imports: [ BrowserModule, HttpClientModule, FormsModule ], providers: [], bootstrap: [AppComponent] })
Więcej wyjaśnień tutaj.
Potem mogłem sobie dodać sprytny warunek *ngIf, który w przypadku braku wartości zmiennej selectedQuiz (pusty lub null) ukrywa cały element <quiz>.
Sprytne. Dodatkowo atrybut ujęty w nawiasy kwadratowe odwołuje się do lokalnego obiektu klasy komponentu, który możemy sobie dowolnie zmieniać:
onSelect(quiz: Quiz) { this.selectedQuiz = quiz; console.log("quiz with Id " + this.selectedQuiz.Id + " has been selected."); }
<ul class="quizzes"> <li>{{quiz.Title}}</li> </ul>
Trochę teorii i mam już do czynienia z pierwszym zdarzenie dostępnym dla komponentów i dyrektyw.
ngOnInit inicjalizuje dyrektywe/komponent i ustawia wszystkie inputy. Dzieje się to tylko raz po pierwszym wystąpieniu innego zdarzenia ngOnChanges.
Więcej na ten temat tutaj.
Następny feature, o którym warto wiedzieć, aby nie być zaskoczonym, że nie musimy osobno deklarować zmiennej prywatnej klasy, aby potem wstrzyknąć ją do niej w konstrukturze. Zamiast pisać:
http: HttpClient; constructor(http: HttpClient, this.http = http; }
można napisać:
constructor(private http: HttpClient) {}
A teraz magiczne wyrażenie two-way data binding, a więc jak zaktualizować model danych lub jego właściwością (po stronie klienta) kiedy aktualizujemy kontrolkę lub zaktualizować kontrolkę kiedy został zaktualizowany model danych. wystarczy ngModel ubrać w okrągły nawias:
<input [(ngModel)]="test.Title" placeholder="Insert the title..."/>
i już.
Jeżeli nie potrzebujemy aktualizować modelu wystarczy usunąć banana brackets () otaczające ngModel. Warto tutaj pochylić się także nad dekoratorem @Input.
Warto pamiętać o tym, że RouterModule znajduje się w pakiecie @angular/router.
Kolejna sprawa to routing. Gdy tylko postanowiłem, że szczegóły obiektu będą wyświetlane na oddzielnej stronie dostałem po oczach:
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'component' of null TypeError: Cannot read property 'component' of null
Rozwiązaniem okazała się potrzeba umieszczenia
w komponencie nadrzędnym. Dodam, że problem wystąpił w routingu opartym na PathLocationStrategy.
I teraz uwaga, najlepiej umieścić w app.component.html
<div class='row'> <div class='col-sm-3'> <nav-menu></nav-menu> </div> <div class='col-sm-9 body-content'> <router-outlet></router-outlet> </div> </div>