0

我正在关注在 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");
      });
  }

}
4

0 回答 0