【问题标题】:angular 6 execute grandparent functions from grandchildangular 6从孙子执行祖父函数
【发布时间】:2018-10-10 11:37:43
【问题描述】:

我需要执行这个祖父组件功能:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  public loginPage = true;

  public login = function(){
    this.loginPage = false;
  }
  public logout = function(){
    this.loginPage = true;
  }

}

来自这个孙子组件:

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

@Component({
  selector: 'app-dropmenu',
  templateUrl: './dropmenu.component.html',
  styleUrls: ['./dropmenu.component.css']
})
export class DropmenuComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

  logout(){
    sessionStorage.removeItem('token');
    **//EXECUTE LOGOUT() GRANDPARENT FUNCTION HERE**
  }
}

我发现与我想要的更接近的例子是创建一个像这样的 DataService:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class DataService {

  private messageSource = new BehaviorSubject('default message');
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(message: string) {
    this.messageSource.next(message)
  }

}

然后在组件中做:

message: string;
this.data.currentMessage.subscribe(message => this.message = message)
//AND
this.data.changeMessage("Hello from Sibling")

但我不想传递任何消息,我只想执行一个函数,那么我真的需要创建那个 DataService 吗?我不能直接在祖父组件中制作一个 Observable 或其他东西吗? 如果是这样,有人可以给我一个例子吗?

【问题讨论】:

  • 您可以解释您的身份验证策略以评论具体问题。可能您可以使用身份验证服务,并且可能是需要身份验证的路由的守卫,如果用户未通过身份验证,可以将守卫配置为重定向到登录页面。
  • 我使用的认证很简单,app.component包含登录页面和主页。该应用程序以 isLoggedIn = false 开头,就像 <app-login *ngIf="!isLoggedIn"></app-login> 一样,如果凭据成功,它会将 isLoggedIn 更改为 true,并像 <app-main *ngIf="isLoggedIn"></app-main> 那样加载主要组件。

标签: angular typescript rxjs


【解决方案1】:

好的,我得到了解决方案,这就是我所做的。

我创建了一个 DataService,它接收来自孩子的按钮点击并使其可观察,以便祖父母可以订阅该主题并检测更改并执行祖父母功能。

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/internal/Subject';
import { Observable } from 'rxjs';

@Injectable()
export class DataService {

    private subject = new Subject();

    constructor() { }

    sendClickLogout() {
        this.subject.next();
    }

    clickLogout(): Observable<any>{
        return this.subject.asObservable();
    }

}

子组件:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../../services/data.service'

@Component({
  selector: 'app-dropmenu',
  templateUrl: './dropmenu.component.html',
  styleUrls: ['./dropmenu.component.css']
})
export class DropmenuComponent implements OnInit {

  constructor(private dataService: DataService) { }

  ngOnInit() {
  }

  logout(){
    this.dataService.sendClickLogout();
  }

}

祖父组件:

import { Component } from '@angular/core';
import { DataService } from '../app/services/data.service'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(private dataService: DataService){
    this.dataService.clickLogout().subscribe(response => { this.logout() });
  }

  public loginPage = true;

  public logout = function(){
    sessionStorage.removeItem('token');
    this.loginPage = true;
  }
}

我希望这对像我这样的人有所帮助。

【讨论】:

  • 如果您要拥有login / logout 功能,请将那些放在服务中,而不是AppComponent...也许AppComponent会收听loginState observable,并显示横幅或其他内容,但我看不出 it 实际注销的原因。
  • 好的开始,但您在设计方面还有更多改进空间。但是只有当你最终处于类似这样的另一种情况时,你才能看到它。还要尝试了解您为什么必须使用服务以及该服务如何解决您的设计问题。
猜你喜欢
  • 2020-04-23
  • 2018-09-04
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多