我正在关注在 Angular Material Design 上构建联系人管理器应用程序的视频教程,该应用程序专为 Angular 和 Angular Material 的第 5 版而设计,但我使用的是 Angular 7.0.4 和 Material 7.2.0。
我正在实现材料选项卡,其中有两个选项卡将联系人的简历与这些联系人的笔记分开。第一个选项卡正确地为每个选项卡提取正确的生物,但第二个选项卡,注释选项卡,不会刷新。无论显示哪个联系人,第二个选项卡都将保留上次联系人刷新浏览器时的注释。由于它默认为第一个联系人,因此每个contact.s 注释都会显示第一个联系人的注释。
联系人和生物的更改由以下 SidNav 组件控制:
sidenav.component.ts
import { Component, OnInit, NgZone, ViewChild } from '@angular/core';
import { UserService } from '../../services/user.service';
import { Observable } from 'rxjs/Observable';
import { User } from '../../models/user';
import { Router } from '@angular/router';
import { MatSidenav } from '@angular/material';
const SMALL_WIDTH_BREAKPOINT = 720;
@Component({
selector: 'app-sidenav',
templateUrl: './sidenav.component.html',
styleUrls: ['./sidenav.component.scss']
})
export class SidenavComponent implements OnInit {
private mediaMatcher: MediaQueryList =
matchMedia(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`);
users: Observable<User[]>;
constructor(
zone: NgZone,
private userService: UserService,
private router: Router) {
this.mediaMatcher.addListener(mql =>
zone.run(() => this.mediaMatcher = matchMedia(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`)));
}
@ViewChild(MatSidenav) sidenav: MatSidenav;
ngOnInit() {
this.users = this.userService.users;
this.userService.loadAll();
this.users.subscribe(data => {
if (data.length > 0) this.router.navigate(['contactmanager', data[0].id]);
});
this.router.events.subscribe(() => {
// tslint:disable-next-line:curly
if (this.isScreenSmall())
this.sidenav.close();
})
}
isScreenSmall(): boolean {
return this.mediaMatcher.matches;
}
}
notes.component.ts:
import { Component, OnInit, Input } from '@angular/core';
import { Note } from '../../models/note';
import { MatTableDataSource } from '@angular/material';
@Component({
selector: 'app-notes',
templateUrl: './notes.component.html',
styleUrls: ['./notes.component.scss']
})
export class NotesComponent implements OnInit {
@Input() notes: Note[];
displayedColumns = ['position', 'title', 'date'];
dataSource: MatTableDataSource<Note>;
constructor() { }
ngOnInit() {
this.dataSource = new MatTableDataSource<Note>(this.notes);
}
}
user.service.ts:
import { Injectable } from '@angular/core';
import { User } from '../models/user';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class UserService {
private _users: BehaviorSubject<User[]>;
private dataStore: {
users: User[]
};
constructor(private http: HttpClient) {
this.dataStore = { users: [] };
this._users = new BehaviorSubject<User[]>([]);
}
get users(): Observable<User[]> {
return this._users.asObservable();
}
userById(id: number) {
return this.dataStore.users.find(x => x.id == id);
}
loadAll() {
const usersUrl = 'https://angular-material-api.azurewebsites.net/users';
return this.http.get<User[]>(usersUrl)
.subscribe(data => {
this.dataStore.users = data;
this._users.next(Object.assign({}, this.dataStore).users);
}, error => {
// tslint:disable-next-line:quotemark
console.log("Failed to fetch users");
});
}
}