首页 > 解决方案 > 尝试从 service.ts 角度调用应用程序组件时,观察者功能在应用程序组件中不起作用

问题描述

我创建了一个响应式侧边菜单,它在应用程序内组件中运行良好,但是当我尝试将该功能移动到我的 service.ts 文件时,它根本不起作用。以下代码适用于我的 app.component.ts

import { Component} from '@angular/core';
import { MyDataServiceService } from './my-data-service.service';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent {
    title = 'azad-app';
    name = '';
    
    constructor(private user: MyDataServiceService) { }
    
    ngAfterViewInit() {
        this.user.menuDisplay();
    }
}

这是我在 service.ts 中的功能代码

import { Injectable, ViewChild } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { BreakpointObserver } from '@angular/cdk/layout';

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

    @ViewChild(MatSidenav)
    sidenav!: MatSidenav;

    constructor(private observer: BreakpointObserver,) { }

    menuDisplay() {
        this.observer.observe(['(max-width:800px)']).subscribe((res) => {
            if (res.matches) {
                this.sidenav.mode = 'over';
                this.sidenav.close();
            } else {
                this.sidenav.mode = "side";
                this.sidenav.open();
            }
        });
    }
}

标签: angularrxjsangular-materialobserver-pattern

解决方案


您应该创建一个指令,而不是使用服务。像这样的东西:

@Directive({selector: 'mat-sidenav[appMenu]'})
export class AppMenu implements OnDestroy{
  private readonly subscription = this.observer.observe(['(max-width:800px)']).subscribe((res) => {
        if (res.matches) {
            this.sidenav.mode = 'over';
            this.sidenav.close();
        } else {
            this.sidenav.mode = "side";
            this.sidenav.open();
        }
    });
  constructor(private readonly sidenav: MatSidenav, private readonly observer: BreakpointObserver){ } 

  ngOnDestroy(){
    this.subscription.unsubscribe();
  }
}

Angular 可以将组件注入到指令中,使用这种方法,您可以将 sidenav 逻辑封装到单独的类中。


推荐阅读