Angular8 开发(二)

2 篇文章 0 订阅

前面已经说到了基本的集成可开发准备工作,Angular 开发(一)。接下来开始逻辑部分的编写

段子列表获取,路由跳转详情

新建段子列表的组件:
ng g c newList 命令的方式会自动在app.module.ts中导入相关组件,declarations中自动声明 NewListComponent
在这里插入图片描述
app-routing.module.ts中增加列表路由,并设置重定向到列表页。并在根组件app.component.html中增加,这样后面的路由页面都会渲染在此!

<div class="root-container">
  <router-outlet></router-outlet>
</div>

app-routing.module.ts主要代码:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { NewListComponent } from "./new-list/new-list.component";
const routes: Routes = [{
    path: "",
    redirectTo: "newList",
    pathMatch: "full"
}, {
    path: "newList",
    component: NewListComponent
}]
@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

新建获取列表和详情的service:
ng g s newList
业务代码:
newlist.service.ts

获取段子列表::
接口:

https://api.apiopen.top/getJoke
type string 否 指定查询类型,可选参数(all/video/image/gif/text) all
page string 否 页码(传0或者不传会随机推荐) 1 count string 否 每页返回数量 10


import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from "@angular/common/http";
import { Observable } from 'rxjs';
@Injectable({
    providedIn: 'root'
})
export class NewlistService {

    constructor(private http: HttpClient) { }
    //获取列表
    getList(type: string, page: number):Observable<any> {
        const params = new HttpParams().set("type", type).set("page", String(page));
        return this.http.request('get',"/getJoke",{
            params
        })
    }
	//获取详情
    getDetail(id:string){
        const params = new HttpParams().set("sid", id);
        return this.http.request('get',"/getSingleJoke",{
            params
        })
    }
}

在这里插入图片描述
这里我使用了http的request,而没有使用其他的get去请求。其他的方法可以自行去Angular官网查看

new-list.component.ts中设置5种type集合以及获取每种type下的数据。

import { Component, OnInit } from '@angular/core';
import { Router } from "@angular/router";
import { NewlistService } from './newlist.service';
@Component({
    selector: 'app-new-list',
    templateUrl: './new-list.component.html',
    styleUrls: ['./new-list.component.scss']
})
export class NewListComponent implements OnInit {
    TypeList = [{
        key: "all",
        text: "全部"
    }, {
        key: "text",
        text: "文字"
    }, {
        key: "video",
        text: "视频"
    }, {
        key: "image",
        text: "图片"
    }, {
        key: "gif",
        text: "动态图"
    }
    ];
    listType = "text";
    page: number = 1;
    DataList: any[] = [];
    initLoading = true;
    loadingMore = false;
    list: Array<{ loading: boolean; name: any }> = [];
    constructor(private newlist: NewlistService, private router: Router) { }
    ngOnInit() {
        this.getList();
    }
    nzSelectChange(select: any) {
        this.DataList = [];
        this.listType = this.TypeList[select.index].key;
        this.page = 1;
        this.getList();
    }

    getList() {
        this.initLoading = true;
        this.newlist.getList(this.listType, this.page).subscribe(res => {
            this.DataList = this.DataList.concat(res);
            this.initLoading = false
        })
    }


    /**
     * 下一页
     */
    onLoadMore() {
        this.page++;
        this.getList()
    }
    details(id) {
        //详情页
        this.router.navigate(['detail'], {
            queryParams: {
                sid: id
            }
        })
    }
    goMusic() {
        //前往music页面:
        this.router.navigate(['musiclist'])
    }
}

new-list.component.html 使用ng-zorro绘制页面

<div>
  <nz-tabset (nzSelectChange)="nzSelectChange($event)">
    <nz-tab [nzTitle]="item.text" *ngFor="let item of TypeList">
      <ng-template nz-tab>
        <nz-list [nzDataSource]="DataList" [nzItemLayout]="'horizontal'" [nzLoading]="initLoading" [nzRenderItem]="item"
          [nzLoadMore]="loadMore">
          <ng-template #item let-items>
            <nz-list-item (click)="details(items.sid)" class="list-item-center">
              <nz-skeleton [nzAvatar]="true" [nzActive]="true" [nzTitle]="false" [nzLoading]="initLoading">
                <nz-card style="width: 300px" nzHoverable [nzCover]="coverTemplate">
                  <nz-card-meta [nzTitle]="titleTemplate" [nzDescription]="items.text" [nzAvatar]="avatarTemplate">
                  </nz-card-meta>
                </nz-card>
                <ng-template #avatarTemplate>
                  <nz-avatar nzIcon="user" [nzSrc]="items.header"></nz-avatar>
                </ng-template>
                <ng-template #titleTemplate>
                  <span>{{items.name}}</span> <span>{{items.passtime}}</span>
                </ng-template>
                <ng-template #coverTemplate>
                  <img *ngIf="items.type=='image'||items.type=='gif'" [src]="items.images" />
                  <img *ngIf="items.type=='video'" [src]="items.thumbnail" />
                </ng-template>
              </nz-skeleton>
            </nz-list-item>
          </ng-template>
          <ng-template #loadMore>
            <div class="loadmore">
              <button nz-button *ngIf="!loadingMore" (click)="onLoadMore()">阅读更多</button>
            </div>
          </ng-template>
        </nz-list>
      </ng-template>
    </nz-tab>
    <nz-tab [nzTitle]="musicTemplate">
      <ng-template #musicTemplate>
        <span (click)="goMusic()"><i nz-icon nzType="play-circle" nzTheme="outline"></i>音乐台</span>
      </ng-template>
    </nz-tab>
  </nz-tabset>
</div>

运行如下:
在这里插入图片描述

获取段子详情

新建详情组件
ng g c detail

app-routing.module.ts中增加detail路由

import { DetailComponent } from "./detail/detail.component";
省略...
 {
    path: "detail",
    component: DetailComponent
}
省略...

列表跳转到详情(detail):列表new-list.component.ts中主要代码

 import { Router } from "@angular/router";
 constructor(private newlist: NewlistService, private router: Router) { }
 details(id) {
        //详情页
        this.router.navigate(['detail'], {
            queryParams: {
                sid: id
            }
        })
    }

可以看到通过queryParams来进行参数传递。学过vue的同学可以类比于router,push 跳转中的params参数。
而详情中通过ActivatedRoute去获取传递过来的参数,如下constructor函数中的实现就是获取sid,当然这里也可以通过snapshot来获取参数,具体用法这里不做赘述

detail.component.ts获取详情代码

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from "@angular/router";
import { NewlistService } from '../new-list/newlist.service';
import { BaseClass } from '../base-class';
@Component({
    selector: 'app-detail',
    templateUrl: './detail.component.html',
    styleUrls: ['./detail.component.scss']
})
export class DetailComponent extends BaseClass implements OnInit {
    Id = ""
    detailData = null
    constructor(private activeRouter: ActivatedRoute, private newListService: NewlistService) {
        super();
        activeRouter.queryParams.subscribe(queryParams => {
            this.Id = queryParams.sid;
        })
    }

    ngOnInit() {
        this.getDetails();
    }
    getDetails() {
        this.newListService.getDetail(this.Id).subscribe(res => {
            this.detailData = res;
            console.log(this.detailData.type)
        })
    }
}

detail.component.html部分

<div class="container">
  <nz-card [nzTitle]="nzTitle">
    <div *ngIf="detailData.type=='video'">
      <video [src]="detailData.video"></video>
    </div>
    <div *ngIf="detailData.type=='image'||detailData.type=='gif'">
      <img [src]="detailData.images" alt="">
    </div>
    <div style="margin-top: 10px;margin-bottom: 10px">
      <span>{{detailData.text}}</span>
    </div>
    <nz-card-meta [nzTitle]="detailData.top_comments_name" [nzDescription]="detailData.top_comments_content"
      [nzAvatar]="avatarTemplate">
    </nz-card-meta>
  </nz-card>
  <ng-template #avatarTemplate>
    <nz-avatar [nzSrc]="detailData.top_comments_header"></nz-avatar>
  </ng-template>
  <ng-template #nzTitle>
    <span (click)="back()"><i nz-icon [nzType]="'left'"></i>返回</span>
  </ng-template>
</div>

渲染详情结果:
在这里插入图片描述

音乐列表搜

创建音乐列表的组件
ng g c musiclist
并增加路由:

import { MusiclistComponent } from "./musiclist/musiclist.component"
省略...
 {
    path: "musiclist",
    component: MusiclistComponent
}
省略...

创建music搜索的service
ng g s music
增加搜索音乐请求方法

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class MusicService {

    constructor(private http: HttpClient) { }
    searchMusic(name: string): Observable<any> {
        const params = new HttpParams().set("name", name);
        return this.http.request("get", "/searchMusic", {
            params
        })
    }
}

musiclist.component.ts 引入musiclist service 进行数据请求
musiclist.component.ts

import { Component, OnInit } from '@angular/core';
import { MusicService } from "./music.service"
import { Router } from '@angular/router';
import { BaseClass } from '../base-class';
@Component({
    selector: 'app-musiclist',
    templateUrl: './musiclist.component.html',
    styleUrls: ['./musiclist.component.scss']
})
export class MusiclistComponent extends BaseClass implements OnInit {
    MusicList = [];
    name = "";
    loading = false;
    constructor(private musicService: MusicService, private router: Router) {
        super();
    }

    ngOnInit() {
    }
    searchMusic() {
        this.loading = true;
        this.musicService.searchMusic(this.name).subscribe(res => {
            if (res != "") {
                this.MusicList = res;
            } else {
                this.MusicList = [];
            }
            this.loading = false;
        })
    }
    playMusic(index: any) {
        console.log(index);
        let list = [];
        this.MusicList.forEach(item => {
            list.push({
                name: item.title,
                artist: item.author,
                url: item.url,
                cover: item.pic,
                theme: '#ebd0c2'
            })
        })
        sessionStorage.setItem("musicList", JSON.stringify(list));
        this.router.navigate(['music'],{
            queryParams:{
                index:index
            }
        })
    }
}

musiclist.component.html 歌曲搜索列表页面:

<div class="music-list-container">
  <nz-input-group nzSearch [nzAddOnAfter]="suffixIconButton">
    <input type="text" [(ngModel)]="name" nz-input placeholder="请输入歌曲关键词" />
  </nz-input-group>
  <ng-template #suffixIconButton>
    <button (click)="searchMusic()" nz-button nzType="primary" nzSearch><i nz-icon type="search"></i></button>
  </ng-template>
  <nz-list [nzDataSource]="MusicList" [nzRenderItem]="item" [nzItemLayout]="'horizontal'" [nzLoading]="loading">
    <ng-template #item let-item let-index="index">
      <nz-list-item (click)="playMusic(index)">
        <nz-card style="width:350px" [nzCover]="coverTemplate">
          <nz-card-meta [nzTitle]="item.author" [nzAvatar]="avatarTemplate" [nzDescription]="item.title">
          </nz-card-meta>
        </nz-card>
        <ng-template #avatarTemplate>
          <nz-avatar nzSrc="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"></nz-avatar>
        </ng-template>
        <ng-template #coverTemplate>
          <img alt="example" [src]="item.pic" />
        </ng-template>
      </nz-list-item>
    </ng-template>
  </nz-list>
</div>

在这里插入图片描述
在这里插入图片描述

渲染搜索的音乐列表和播放音乐

新建播放组件
ng g c music
导入APlayer

import APlayer from 'APlayer';

并在ngOnInit生命周期内实例化APlayer

const List = JSON.parse(sessionStorage.getItem("musicList"));
        const ap = new APlayer({
            container: document.getElementById('aplayer'),
            audio: List
        });
        ap.list.switch(this.index);//切换至列表页点击的歌曲

其中sessionStorage.getItem("musicList")获取列表页搜索到的歌曲,赋值给Aplayer中的audio字段。实现列表展示。

ap.list.switch(this.index),其中switch是展示列表页面点击的歌曲索引,实现播放点击的歌曲。this.index为列表传递过来的:

musiclist.component.ts跳转播放页并传递数据:

 playMusic(index: any) {
        console.log(index);
        let list = [];
        this.MusicList.forEach(item => {
            list.push({
                name: item.title,
                artist: item.author,
                url: item.url,
                cover: item.pic,
                theme: '#ebd0c2'
            })
        })
        sessionStorage.setItem("musicList", JSON.stringify(list));
        this.router.navigate(['music'],{
            queryParams:{
                index:index
            }
        })
    }

歌曲播放获取列表传递过来的index数据 :

 constructor(private activeRoute: ActivatedRoute) {
        activeRoute.queryParams.subscribe(params => {
            this.index = params.index;
        })
    }

播放歌曲完整:

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

import APlayer from 'APlayer';
import { ActivatedRoute } from '@angular/router';
@Component({
    selector: 'app-music',
    templateUrl: './music.component.html',
    styleUrls: ['./music.component.scss']
})
export class MusicComponent implements OnInit {
    index = ""
    constructor(private activeRoute: ActivatedRoute) {
        activeRoute.queryParams.subscribe(params => {
            this.index = params.index;
        })
    }

    ngOnInit() {
        const List = JSON.parse(sessionStorage.getItem("musicList"));
        const ap = new APlayer({
            container: document.getElementById('aplayer'),
            audio: List
        });
        ap.list.switch(this.index);//切换至列表页点击的歌曲
    }

}

跳转播放页面:
在这里插入图片描述

总结

该Demo,麻雀虽小,五脏俱全,其 结合使用了angular基本的指令、管道、数据双向绑、事件、 http的封装统一拦截响应处理,路由的定义、使用,以及组件的引入,服务引入和编写、模板的编写等等Angular技术,rxjs 的使用,ng-zorro的使用。

源码地址

其中有使用不正确,或者有更好的建议,欢迎指正~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值