Mit Angular meinen wir Angular 2.
In diesem Lernprogramm erstellen wir eine iTunes-Suchanwendung. Die App verwendet die offene iTunes JSONP-API, um nach Künstlern zu suchen und Alben dieses Künstlers in einem Kendo-UI-Raster anzuzeigen. Jedes Album wird erweitert, um ein Detailraster anzuzeigen, das alle Titel enthält. Jeder Titel kann mit Web Audio abgespielt werden.
Sie können die fertige Anwendung anzeigen und den gesamten Code auf GitHub abrufen. Wenn Sie an irgendeinem Punkt nicht weiterkommen, empfehle ich, das abgeschlossene Projekt als Referenz herunterzuladen.
Voraussetzungen
- Die Winkel-CLI
Erstellung der App
Erstellen Sie zunächst eine neue Anwendung, in der Sie Sass als bevorzugte Stilsprache angeben. Wenn Sie Sass nicht kennen, machen Sie sich keine Sorgen. Sie können immer noch einfaches altes CSS in Sass-Dateien schreiben. Die Verwendung von Sass gibt uns nur die Möglichkeit, Stilbibliotheken von Drittanbietern einfach einzubinden. Die Angular-CLI verdrahtet alle erforderlichen Build-Schritte.
> ng new itunes-search -style=scss && cd itunes-search
Führen Sie die Anwendung aus und lassen Sie sie geöffnet. Die Anwendung läuft normalerweise auf Port 4200. Eine ausführlichere Erklärung finden Sie in diesem Artikel.
> ng serve
Installieren Sie als Nächstes das Bootstrap-Sass-Paket von npm.
> npm install bootstrap-sass --save
Fügen Sie die Bootstrap-Sass-Referenzen zu Ihrem Projekt in 05
hinzu Datei.
/* You can add global styles to this file, and also import other style files */
/* Bootstrap CSS And Icon Font */
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
@import "~bootstrap-sass/assets/stylesheets/bootstrap";
Die App wird automatisch aktualisiert. Aufgrund der von Bootstrap verwendeten serifenlosen Schriftart sieht es etwas anders aus.
Fügen Sie das folgende Markup zu 18
hinzu .
<div class="container">
<h1>iTunes Search</h1>
<!-- Artist Component Will Go Here -->
<!-- Audio Player Component Will Go Here -->
</div>
Erstellen eines Dienstes
Erstellen Sie als Nächstes einen Dienst, der die JSON-API von iTunes Search aufruft. Der Angular Style Guide empfiehlt, diese in einem „freigegebenen“ Ordner abzulegen, erstellen Sie also den freigegebenen Ordner unter 22
.
> mkdir src/app/shared
Erstellen Sie den Dienst mit den Angular-CLI-Generatoren, die Komponenten, Dienste und dergleichen aufbauen.
> ng generate service shared/itunes
Öffnen Sie die 31
Datei und fügen Sie den Code hinzu, der 49
importiert Unterstützung für Angular 2, die 55
und 67
Methoden von rxjs und stellt eine Funktion bereit, die den HTTP-Aufruf an den iTunes-Dienst sendet und ein Promise zurückgibt.
import { Injectable } from '@angular/core';
import { Jsonp } from '@angular/http';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/toPromise';
const API = {
SEARCH: 'https://itunes.apple.com/search?',
LOOKUP: 'https://itunes.apple.com/lookup?'
}
@Injectable()
export class ItunesService {
constructor(private jsonp: Jsonp) {
}
public search(searchTerm): Promise<any> {
return this.jsonp.get(`${API.SEARCH}callback=JSONP_CALLBACK&media=music&country=US&entity=musicArtist&term=${searchTerm}`)
.toPromise()
.then(data => data.json().results)
.catch(this.handleError)
}
private handleError(error: any): Promise<any> {
console.log(error);
return Promise.reject(error.message || error);
}
}
Die 77
Modul muss auch in 87
eingefügt werden Datei, sonst steht sie hier im Dienst nicht zur Verfügung.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
// Include the JSONP module for JSONP support
import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
// include the JSONP module so it can be used in the application
JsonpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Komponenten erstellen
Jetzt fügen wir die Künstlerkomponente hinzu, die die Suchleiste und Künstlerergebnisse enthält. Es ruft auch den iTunes-Dienst auf, um nach Künstlern zu suchen.
> ng generate component artist
Dadurch wird ein 98
erstellt Mappe. Es fügt auch die Komponente in 105
ein Datei, damit sie in der Anwendung verwendet werden kann. Die Angular-CLI erledigt all dies, wenn Sie 113
verwenden Befehl.
Fügen Sie das folgende Markup zu 125
hinzu Datei.
<div class="row">
<div class="col-xs-12">
<input type="search" #searchBox (keyup)="search(searchBox.value)" class="form-control input-lg well" placeholder="Type to search for artist...">
</div>
</div>
<div class="row">
<div class="col-sm-4" *ngIf="searchResults.length > 0">
<h3>Search Results</h3>
<p *ngFor="let artist of searchResults">
<a id="{{ artist.artistId }}" href="#" (click)="getAlbums(artist.artistId, artist.artistName)">{{ artist.artistName }}</a>
</p>
</div>
<div class="col-xs-12" [ngClass]="{'col-sm-8': searchResults.length > 0 }">
<h3>{{ selectedArtist }}</h3>
<!-- App Album Component Goes Here -->
</div>
</div>
Dieses Markup erstellt das Suchfeld und ein zweispaltiges Layout für die Künstlersuchergebnisse auf der linken Seite. Wenn der Benutzer auf einen Künstler klickt, werden alle Alben dieses Künstlers in einem Raster auf der rechten Seite angezeigt.
Öffnen Sie die 131
Datei. Fügen Sie den erforderlichen Code hinzu, um die Bindung von 143
zu unterstützen Datei. Es benötigt einen 153
-Methode zum Aufrufen des iTunes-Dienstes, wenn der Benutzer eintippt, sowie eine Sammlung von 166
die auf der Seite angezeigt wird, und schließlich ein 177
Ereignis, das ausgelöst wird, wenn der Benutzer auf ein Künstlerergebnis klickt.
import { Component } from '@angular/core';
import { ItunesService } from '../shared/itunes.service';
@Component({
selector: 'app-artist',
templateUrl: './artist.component.html',
providers: [ItunesService]
})
export class ArtistComponent {
searchResults: Array<any> = [];
artistId: number = 0;
selectedArtist: string;
constructor(private itunesService: ItunesService) { }
search(searchTerm) {
this.itunesService.search(searchTerm).then(results => {
this.searchResults = results;
});
}
getAlbums(artistId: number, artistName: string) {
this.artistId = artistId;
this.selectedArtist = artistName;
}
}
Aufrufen des iTunes-Dienstes
Jetzt fügen wir die Möglichkeit hinzu, Alben nach Interpreten vom iTunes-Dienst abzurufen. Öffnen Sie 187
Datei und fügen Sie Folgendes hinzu.
private _albums: Array<any> = [];
private _artistId: number = 0;
// Get Albums Method
public getAlbums(artistId: number): Promise<any> {
if (artistId == this._artistId) return new Promise(resolve => resolve(this._albums));
this._artistId = artistId;
return this.jsonp.get(`${API.LOOKUP}callback=JSONP_CALLBACK&entity=album&id=${artistId}`)
.toPromise()
.then(data => {
this._albums = data.json().results.filter(results => {
return results.wrapperType == 'collection'
});
return this._albums;
})
.catch(this.handleError);
}
Dieser Code enthält eine neue Funktion, 196
das Alben nach Künstler-ID von der iTunes-API abruft. Außerdem werden Aufrufe an 200
zwischengespeichert falls die Funktion wiederholt mit den gleichen Parametern aufgerufen wird. Benutzeroberflächen tun dies häufig.
Erstellen Sie als Nächstes die Album-Komponente mit dem Angular-CLI-Komponentengenerator.
> ng generate component album
Hinzufügen in der Kendo-Benutzeroberfläche
Fügen Sie nun das Kendo UI Grid für Angular hinzu. Bevor Sie dies tun, stoppen Sie den Dev-Server, indem Sie 213
drücken . Dies ist bei der Kendo-Benutzeroberfläche erforderlich, um sicherzustellen, dass Dateien, die kopiert werden müssen, nicht verwendet werden.
> npm login --registry=https://registry.npm.telerik.com/ --scope=@progress
> npm install --save @progress/kendo-angular-grid
> npm install --save @progress/kendo-data-query
> npm install -S @telerik/kendo-theme-default
> ng serve
Verweisen Sie auf das Standarddesign der Kendo-Benutzeroberfläche in 222
Datei.
@import "~@telerik/kendo-theme-default/styles/packages/all";
Fügen Sie das Kendo UI Grid zu 239
hinzu Datei.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { ArtistComponent } from './artist/artist.component';
// Import Kendo UI Grid
import { GridModule } from '@progress/kendo-angular-grid';
@NgModule({
declarations: [
AppComponent,
ArtistComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
JsonpModule,
// Register the Kendo UI Grid
GridModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Fügen Sie nun das folgende Markup zum 245
hinzu Datei.
<kendo-grid
[data]="view"
>
<kendo-grid-column field="artworkUrl60" title=" " width="95">
<template kendoCellTemplate let-dataItem>
<img src="{{ dataItem.artworkUrl60 }}">
</template>
</kendo-grid-column>
<kendo-grid-column field="collectionName" title="Album Title"></kendo-grid-column>
<kendo-grid-column field="releaseDate" title="Release Date">
<template kendoCellTemplate let-dataItem>
<p>{{ dataItem.releaseDate | date }}</p>
</template>
</kendo-grid-column>
<div *kendoDetailTemplate="let dataItem">
<!-- Tracks Component Goes Here -->
</div>
</kendo-grid>
Alben nach Künstler abrufen
Fügen Sie die Logik für die Album-Komponente hinzu, die Alben vom iTunes-Dienst basierend auf einer Künstler-ID einzieht.
import { Component, Input } from '@angular/core';
import { ItunesService } from '../shared/itunes.service';
import { GridDataResult } from '@progress/kendo-angular-grid';
@Component({
selector: 'app-album',
templateUrl: './album.component.html',
providers: [ItunesService]
})
export class AlbumComponent {
private view: GridDataResult;
@Input()
set artistId(artistId: number) {
this._artistId = artistId;
// get the albums for this artist
this.getAlbums();
}
get artistId() { return this._artistId }
constructor(private itunesService: ItunesService) { }
getAlbums() {
this.itunesService.getAlbums(this.artistId).then((results: Array<any>) {
this.view = {
data: results,
total: results.length
}
});
}
}
Der 256
ermöglicht es uns, eine Variable in der Album-Komponente anzugeben, die von der übergeordneten Komponente festgelegt werden kann, in diesem Fall der Artist-Komponente. Wir verwenden einen Setter, um sicherzustellen, dass jedes Mal, wenn die Artist-Komponente eine Artist-ID festlegt, die Alben-Komponente den Inhalt des Rasters aktualisiert, indem sie 260
aufruft . Dies ist eine Möglichkeit, wie Angular-Komponenten miteinander kommunizieren können. Weitere Informationen finden Sie unter Komponenteninteraktion in der Angular-Dokumentation.
Fügen Sie die Albumkomponente zu 275
hinzu Datei. Beachten Sie die Verwendung von 286
, die an 299
übergeben wird .
<div class="row">
<div class="col-xs-12">
<input type="search" #searchBox (keyup)="search(searchBox.value)" class="form-control input-lg well" placeholder="Type to search for artist...">
</div>
</div>
<div class="row">
<div class="col-sm-4" *ngIf="searchResults.length > 0">
<h3>Search Results</h3>
<p *ngFor="let artist of searchResults">
<a id="{{ artist.artistId }}" href="#" (click)="getAlbums(artist.artistId, artist.artistName)">{{ artist.artistName }}</a>
</p>
</div>
<div class="col-xs-12" [ngClass]="{'col-sm-8': searchResults.length > 0 }">
<h3>{{ selectedArtist }}</h3>
<!-- App Album-->
<app-album [artistId]="artistId" *ngIf="artistId > 0"></app-album>
</div>
</div>
Jetzt zeigt die Alben-Komponente Alben an, wenn ein Künstler ausgewählt wird.
Durch die Ergebnisse blättern
Fügen Sie Paging zum Grid hinzu, indem Sie das Grid auf pageable setzen, die Seitengröße definieren (wie viele Datensätze pro Seite angezeigt werden), den Skip-Parameter (wie viele Datensätze vom Beginn der Sammlung zu überspringen) und den 301
315
.
<kendo-grid
[data]="view"
[pageSize]="pageSize"
[skip]="skip"
[pageable]="true"
(pageChange)="pageChange($event)"
>
.... Grid Content Omitted For Berevity ....
</kendo-grid>
Ändern Sie 327
Datei zur Handhabung des 335
Ereignis durch Aufrufen des 342
-Methode erneut und trimmen Sie das resultierende Array auf die richtigen Elemente für die aktuelle Seite.
import { Component, Input } from '@angular/core';
import { ItunesService } from '../shared/itunes.service';
import { GridDataResult, PageChangeEvent } from '@progress/kendo-angular-grid';
import { SortDescriptor, orderBy } from '@progress/kendo-data-query';
@Component({
selector: 'app-album',
templateUrl: './album.component.html',
providers: [ItunesService]
})
export class AlbumComponent {
view: GridDataResult;
_artistId: number = 0;
// controls grid paging settings
private pageSize: number = 5;
private skip: number = 0;
@Input()
set artistId(artistId: number) {
this._artistId = artistId;
// get the albums for this artist
this.getAlbums();
}
get artistId() { return this._artistId }
constructor(private itunesService: ItunesService) { }
getAlbums() {
this.itunesService.getAlbums(this.artistId).then((results: Array<any>) {
this.view = {
// slice the album result to get only the selected page of data
data: results.slice(this.skip, this.skip + this.pageSize),
total: results.length
}
});
}
// fires when the user changes pages in the grid
protected pageChange(event: PageChangeEvent): void {
this.skip = event.skip;
this.getAlbums();
}
}
The Grid hat jetzt Paging-Unterstützung.
Detaillierte Streckenergebnisse anzeigen
Neben jeder Zeile befindet sich ein kleines „+“-Symbol, das darauf hinweist, dass Sie die Zeile erweitern können, um weitere Informationen anzuzeigen. Im Moment passiert nichts. Das gewünschte Verhalten besteht darin, alle verfügbaren Spuren für das ausgewählte Element anzuzeigen. Dazu benötigen wir eine Tracks-Komponente.
Fügen Sie zuerst einen 358
hinzu Methode zum 362
Datei, die alle Tracks für eine bestimmte Album-ID zurückgibt.
public getTracks(albumId: number): Promise<any> {
return this.jsonp.get(`${API.LOOKUP}callback=JSONP_CALLBACK&entity=song&id=${albumId}`)
.toPromise()
.then(data => {
return data.json().results.filter(result => {
return result.wrapperType == 'track';
});
})
.catch(this.handleError)
}
Erstellen Sie die Tracks-Komponente mit der Angular-CLI.
> ng generate component track
Öffnen Sie den 372
Datei und fügen Sie das folgende Markup hinzu.
<kendo-grid
[data]="view"
[scrollable]="'none'"
>
<kendo-grid-column width="50">
<template kendoCellTemplate let-dataItem>
<!-- Track Control Component Goes Here -->
</template>
</kendo-grid-column>
<kendo-grid-column field="trackCensoredName" title="Track Name">
</kendo-grid-column>
</kendo-grid>
Fügen Sie den folgenden Code zu 387
hinzu Datei. Beachten Sie die Verwendung des 394
-Parameter, um die Album-ID an die Tracks-Komponente zu übergeben. Dies ist genau dieselbe Funktion, die verwendet wurde, um die Künstler-ID von der Künstlerkomponente an die Albumkomponente zu übergeben.
import { Component, OnInit, Input } from '@angular/core';
import { ItunesService } from '../shared/itunes.service';
@Component({
selector: 'app-track',
templateUrl: './track.component.html',
styleUrls: ['./track.component.scss'],
providers: [ItunesService]
})
export class TrackComponent implements OnInit {
view: Array<any>
@Input()
set collectionId(collectionId: number) {
this.getTracks(collectionId);
}
constructor(private itunesService: ItunesService) { }
ngOnInit() {
}
private getTracks(collectionId: number) {
this.itunesService.getTracks(collectionId).then(result => {
this.view = result;
});
}
}
Fügen Sie nun die Tracks-Komponente zu 407
hinzu Datei.
<kendo-grid
[data]="view"
[pageSize]="pageSize"
[skip]="skip"
[pageable]="true"
(pageChange)="pageChange($event)"
>
<kendo-grid-column field="artworkUrl60" title=" " width="95">
<template kendoCellTemplate let-dataItem>
<img src="{{ dataItem.artworkUrl60 }}">
</template>
</kendo-grid-column>
<kendo-grid-column field="collectionName" title="Album Title"></kendo-grid-column>
<kendo-grid-column field="releaseDate" title="Release Date">
<template kendoCellTemplate let-dataItem>
<p>{{ dataItem.releaseDate | date }}</p>
</template>
</kendo-grid-column>
<div *kendoDetailTemplate="let dataItem">
<!-- Tracks Component -->
<app-track [collectionId]="dataItem.collectionId"></app-track>
</div>
</kendo-grid>
Audio abspielen
Die iTunes-API stellt für jeden Titel eine URL zu einem Audiobeispiel bereit. Der Browser kann die Web Audio API verwenden, um diese Tracks abzuspielen.
Erstellen Sie eine Player-Komponente, die den Audio-Player für die Anwendung steuert.
> ng generate component player
Fügen Sie dem 414
das folgende Markup hinzu Datei.
<audio #player="" style="display: none" (ended)="playerEnded()">
Fügen Sie den folgenden Code zu 425
hinzu Datei. Dies behandelt die Einstellung der Audioquelle (src) für den Player sowie die Handhabung, was zu tun ist, wenn ein Track-Sample beendet wird.
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
selector: 'app-player',
templateUrl: './player.component.html',
styleUrls: ['./player.component.scss']
})
export class PlayerComponent implements OnInit {
@ViewChild('player') playerRef;
player: any;
constructor() {}
ngOnInit() {
this.player = this.playerRef.nativeElement;
}
playerEnded() {
// handle event
}
}
Fügen Sie die Player-Komponente zu 430
hinzu . Es gibt nur eine Audiosteuerung für die gesamte Anwendung. Alle Tracks verwenden diesen Audioplayer, wenn der Benutzer auf das „Play“-Symbol neben einem Track klickt.
<div class="container">
<h1>iTunes Search</h1>
<!-- Artist Component -->
<app-artist></app-artist>
<!-- Audio Player Component -->
<app-player></app-player>
</div>
Erstellen Sie als Nächstes eine Track-Steuerungskomponente, die Play/Pause-Schaltflächen für jeden Track erstellt und mit der Player-Komponente kommuniziert.
> ng generate component track/track-control
Beachten Sie, dass diese Komponente im Track Component-Ordner verschachtelt ist. Dies liegt daran, dass sie zwar nicht direkt voneinander abhängig sind, aber sehr eng miteinander verwandt sind und daher logisch in eine hierarchische Struktur gehören.
Fügen Sie das folgende Markup zu 445
hinzu Datei, um die Wiedergabe-/Pause-Symbole mit der Bootstrap-Symbolschriftart anzuzeigen.
<div>
<span *ngif="!isPlaying" class="glyphicon glyphicon-play" aria-hidden="true" (click)="playTrack()"></span>
<span *ngif="isPlaying" class="glyphicon glyphicon-pause" aria-hidden="true" (click)="pauseTrack()"></span>
</div>
Fügen Sie den Code zu 457
hinzu , das den Status des Titels (isPlaying) sowie die Klickereignisse der Wiedergabe-/Pause-Symbole steuert.
import { Component, OnDestroy, Input } from '@angular/core';
@Component({
selector: 'app-track-control',
templateUrl: './track-control.component.html',
styleUrls: ['./track-control.component.sass']
})
export class TrackControlComponent {
isPlaying: boolean = false;
@Input() public track: any;
constructor() { }
playTrack() {
this.isPlaying = true;
}
pauseTrack() {
this.isPlaying = false;
}
}
Fügen Sie nun die Track Control-Komponente zu 466
hinzu Datei.
<kendo-grid
[data]="view"
[scrollable]="'none'"
>
<kendo-grid-column width="50">
<template kendoCellTemplate let-dataItem>
<!-- Track Control Component -->
<app-track-control [track]="dataItem"></app-track-control>
</template>
</kendo-grid-column>
<kendo-grid-column field="trackCensoredName" title="Track Name">
</kendo-grid-column>
</kendo-grid>
An diesem Punkt wird jeder Track eine Play/Pause-Schaltfläche anzeigen. Jeder Track kennt auch seine eigene URL für das entsprechende Audio-Sample. Die Track Control-Komponente kann jedoch noch nicht mit der Player-Komponente kommunizieren, sodass während die Schaltfläche von einem Wiedergabe- in einen angehaltenen Zustand wechselt, tatsächlich kein Audio wiedergegeben wird.
Um diese Kommunikation zu erleichtern, verwenden wir einen Shared Service. Erstellen Sie einen neuen Dienst namens Player Service.
> ng create service shared/player
Der Player-Dienst enthält einige rxjs-Abonnements, die andere Komponenten abonnieren können. Auf diese Weise können Komponenten Ereignisse auslösen und andere Komponenten auf diese Ereignisse reagieren, obwohl sie überhaupt nicht wissen, dass die andere Komponente existiert. Weitere Informationen zur Kommunikation über gemeinsame Dienste finden Sie in der offiziellen Angular-Dokumentation.
Fügen Sie den folgenden Code zu 479
hinzu Datei.
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/subject';
@Injectable()
export class PlayerService {
private playTrackSource = new Subject<string>();
private pauseTrackSource = new Subject();
private trackEndedSource = new Subject();
playTrack$ = this.playTrackSource.asObservable();
pauseTrack$ = this.pauseTrackSource.asObservable();
trackEnded$ = this.trackEndedSource.asObservable();
playTrack(previewUrl: string) {
this.playTrackSource.next(previewUrl);
}
pauseTrack() {
this.pauseTrackSource.next();
}
trackEnded() {
this.trackEndedSource.next();
}
}
Fügen Sie den Dienst in 489
ein Datei. Dieser lauscht, wenn ein Titel ausgewählt wird, und spielt die Datei ab. Es stoppt auch die Wiedergabe einer Datei, wenn der Benutzer auf die Pause-Schaltfläche klickt. Schließlich löst es ein Ereignis aus, wenn das Sample vollständig abgespielt ist.
import { Component, OnInit, ViewChild } from '@angular/core';
import { PlayerService } from '../shared/player.service';
@Component({
selector: 'app-player',
templateUrl: './player.component.html',
styleUrls: ['./player.component.scss']
})
export class PlayerComponent implements OnInit {
@ViewChild('player') playerRef;
player: any;
constructor(private playerService: PlayerService) {
playerService.playTrack$.subscribe(previewUrl => {
this.playTrack(previewUrl);
});
playerService.pauseTrack$.subscribe(() => {
this.pauseTrack();
})
}
ngOnInit() {
this.player = this.playerRef.nativeElement;
}
playTrack(previewUrl) {
this.player.src = previewUrl;
this.player.play();
}
pauseTrack() {
this.player.pause();
}
playerEnded() {
this.playerService.trackEnded();
}
}
Ändern Sie 493
Datei, um auch auf Trigger-Track-Ereignisse über den Dienst zu hören.
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { PlayerService } from '../../shared/player.service';
import { Subscription } from 'rxjs/subscription';
@Component({
selector: 'app-track-control',
templateUrl: './track-control.component.html',
styleUrls: ['./track-control.component.sass']
})
export class TrackControlComponent implements OnInit, OnDestroy {
isPlaying: boolean = false;
@Input() public track: any;
playSub: Subscription;
endedSub: Subscription;
constructor(private playerService: PlayerService) {
this.playSub = playerService.playTrack$.subscribe(
track => {
this.isPlaying = false;
});
this.endedSub = playerService.trackEnded$.subscribe(() => {
this.isPlaying = false;
})
}
ngOnInit() {
}
ngOnDestroy() {
// clean up any subscriptions we aren't using anymore
this.playSub.unsubscribe();
this.endedSub.unsubscribe();
}
playTrack() {
this.playerService.playTrack(this.track.previewUrl);
this.isPlaying = true;
}
pauseTrack() {
this.playerService.pauseTrack();
this.isPlaying = false;
}
}
Zuletzt fügen Sie den Dienst in 508
ein . Diese Komponente ist die oberste Ebene sowohl für die Player-Komponente als auch für die Track-Steuerungskomponente. Wenn Sie den Dienst hier einfügen, wird er automatisch irgendwo weiter unten im Komponentenbaum eingefügt, wenn darauf verwiesen wird.
import { Component } from '@angular/core';
import { PlayerService } from './shared/player.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
providers: [PlayerService]
})
export class AppComponent {
}
Jetzt spielt die App Musik ab, wenn auf die Wiedergabeschaltfläche neben einem Titel geklickt wird. Darüber hinaus wird durch das Abspielen eines anderen Titels während der Wiedergabe eines Titels der richtige Zustand für die Wiedergabeschaltfläche sowohl für den neu wiedergegebenen Titel als auch für den zuvor wiedergegebenen Titel festgelegt. So verwaltet Angular 2 ziemlich komplexe Zustände.
Holen Sie sich die Kendo-UI für Angular-Komponenten
In diesem Artikel haben Sie gesehen, wie Sie ein Raster mit Daten füllen, Paging verwenden und sogar Detailraster verdrahten. The Grid kann viel und mehr als nur das. Ich empfehle dringend, sich die Grid-Tutorials anzusehen.
Die fertige App können Sie hier sehen. Der gesamte Code aus diesem Artikel ist auf GitHub verfügbar. Befolgen Sie die README-Anweisungen, um es einzurichten und auf Ihrem eigenen Computer auszuführen.