【问题标题】:Angular 6 - Passing variable valueAngular 6 - 传递变量值
【发布时间】:2023-03-07 22:01:01
【问题描述】:

是否有任何选项可以仅将 Component1 中保存的一个变量的值传递给 Component2 中的变量而不进行任何模板绑定?

我有组件 Header 和 Footer,并且在 header 中有一个布尔变量 test,我需要将变量 TEST 的值传递给 Footer 组件中的变量 TEST2。

我正在寻找一些带有 @Input 的解决方案,但我没有找到任何没有模板绑定的解决方案,如 [test]="test"

简而言之,我只需要将值从一个 .ts 文件传递​​到另一个 .ts 文件。

我在关注这个例子:Pass data to nth level child component in Angular 4

但是变量仍然没有传递给组件

HeaderService.ts

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

@Injectable()
export class HeaderService {
    getTheme: boolean;
}

HeaderComponent.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { SideBarService } from '../sidebar/sidebar.service';
import { googleMapConfig } from '../content/google-map/config.service';
import { HeaderService } from './header.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
  encapsulation: ViewEncapsulation.None,
})

export class HeaderComponent implements OnInit {

  Name = 'Menučkáreň';
  Navigation = 'Navigácia';
  nightTheme;

  icons = ['favorites','notification_important'];
  tooltip = ['Obľúbené položky','Zoznam zmien'];

  constructor(
    public sideBarService: SideBarService,
    public mapService: googleMapConfig,
    private headerService: HeaderService
  ) { }

public toggle() {
  this.sideBarService.toggle.emit();
}

public changeDark() {
  this.nightTheme = true;
  this.headerService.getTheme = true;
  this.mapService.changeDark.emit();
}

public changeLight() {
  this.nightTheme = false;
  this.headerService.getTheme = false;
  this.mapService.changeLight.emit();
}

  ngOnInit() { }

}

页脚组件

import { Component } from '@angular/core';
import { HeaderService } from '../header/header.service';

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss'],
  providers: [HeaderService]
})
export class FooterComponent {

  Copyright = 'Copyright 2018 | Vytvoril Patrik Spišák';
  Version = '0.0.1';
  nightTheme: boolean;

  constructor(private headerService: HeaderService) {

    this.nightTheme = this.headerService.getTheme;

   }

}

所以当我从 HeaderComponent.html 调用我的函数 changeDark() 时,它不会触发 this.headerService.getTheme = true;

 <mat-grid-tile>
              <button (click)="this.changeDark($event)" mat-icon-button>
                <mat-icon aria-label="Nočný režim">brightness_3</mat-icon>
              </button>
          </mat-grid-tile>

更新

所以我能够通过这段代码实现我所需要的:问题在于在 FooterComponent 中声明的提供程序。虽然在 FootersComponent 中声明了提供程序,但我得到了未定义,当我删除它们并仅在 app.modules.ts 变量中保留提供程序时,已正确设置和读取。

HeaderService.ts

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

@Injectable()
export class HeaderService {
    nightTheme:boolean;

    get data():boolean{
        return this.nightTheme;
    }

    set data(value:boolean){
        this.nightTheme = value;
    }

constructor(){}
}

标题组件

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { SideBarService } from '../sidebar/sidebar.service';
import { googleMapConfig } from '../content/google-map/config.service';
import { HeaderService } from './header.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
  encapsulation: ViewEncapsulation.None,
})

export class HeaderComponent implements OnInit {

  Name = 'Menučkáreň';
  Navigation = 'Navigácia';

  icons = ['favorites','notification_important'];
  tooltip = ['Obľúbené položky','Zoznam zmien'];

  constructor(
    public sideBarService: SideBarService,
    public mapService: googleMapConfig,
    private headerService: HeaderService
  ) {}

public toggle() {
  this.sideBarService.toggle.emit();
}

public changeDark() {
  this.headerService.nightTheme = true;
  console.log(this.headerService.nightTheme);
  this.mapService.changeDark.emit();
}

public changeLight() {
  this.headerService.nightTheme = false;
  console.log(this.headerService.nightTheme);
  this.mapService.changeLight.emit();
}

  ngOnInit() { }

}

页脚组件

import { Component, OnInit } from '@angular/core';
import { HeaderService } from '../header/header.service';

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.scss'],
})
export class FooterComponent {

  Copyright = 'Copyright 2018 | Vytvoril Patrik Spišák';
  Version = '0.0.1';

  constructor(private headerService: HeaderService) { }

  ngOnInit() {
    console.log('FOOTER:'+this.headerService.nightTheme);
  }
  
}

【问题讨论】:

  • 您不能... 使用通用服务或模板语法。组件不应紧密耦合
  • 你不能访问组件的属性,但是你可以访问你不想访问的组件中服务内部的值。
  • 在您的源代码中,您没有在任何地方调用 changeDark 和 changeLight ,这就是您为服务设置值的地方。另外,我建议您通过编辑将源代码移至问题并删除答案。
  • 对不起,我已经编辑了我的帖子。您可以看到实际上我调用了触发我定义的事件的函数,除了我需要传递给页脚组件的最后一个事件
  • @PatrikSpišák,在你的组件中使用 getter:不要声明 nightTheme,只需:get nightTheme(){ return this.headerService.getTheme;}

标签: angular typescript


【解决方案1】:

您可以使用一个服务来存储变量并且组件可以从中访问它。更多关于这里的服务:https://angular.io/tutorial/toh-pt4

【讨论】:

    【解决方案2】:

    看看官方angular documentation - 父母和孩子通过服务进行交流。这个想法是创建一个具有一些 RxJS Subject 属性的服务。您的组件将注入此服务并使用这些Subjects - 它们可以相互交互。为什么Subject?因为您可以同时订阅和发出值。有关更多信息 - 请查看有关 understanding subjects 的这篇文章。

    如果您不熟悉 RxJS 主题,作为一种解决方法(但这不是一个好的解决方案) - 您可以通过更改其属性来共享同一服务的值。但在这种情况下,如果有任何更改,您的组件将无法收到通知。这就是为什么主题是通过服务进行组件交互的理想候选者。

    【讨论】:

      【解决方案3】:

      您可以使用 Angular 服务在您的组件之间共享您的公共数据。请看我的回答

      Pass data to nth level child component in Angular 4

      另外一个选项是 RxJs ,你可以通过 Observable 与一些孤立的组件进行通信

      Angular 6 communication between component and a directive

      【讨论】:

        【解决方案4】:

        更新

        @PatrikSpišák,当您使用 getter 时,应用程序中的任何更改都会强制 Angular “重新计算”该值。 “提示”是您只有一个变量(该变量是服务中定义的变量)。制作一个 getter 使您可以在组件的 .html 中使用“getter”。您可以使用 getter 对组件的其他变量进行任何更改

        更新 2(更正了变量的名称)

        您的页脚组件。 footer 需要知道 getTheme 的值

        constructor(private headerService: HeaderService) 
        get getTheme()
        {
            return this.headerService.getTheme;
        }
        

        你的 header 组件,header 需要知道 nightTheme 的值并且可以改变

        constructor(private headerService: HeaderService) 
        get getTheme()
        {
            return this.headerService.getTheme;
        }
        set getTheme(value)
        {
            this.headerService.getTheme=value;
        }
        //You can do anywhere
        this.getTheme=true
        

        您的服务标头服务

        getTheme:any;
        constructor(){}
        

        headerService 中只有一个变量 getTheme(等同于您可以使用另一个变量)。看到你的代码我想你想提到“nightTheme”

        【讨论】:

        • 但我根本不需要展示价值。我只需要将值从 in.Header.ts 中的一个变量传递到 Footert.ts 中的另一个变量 问题是我在 Header 和 Footer 组件中有相同的变量(nightTheme)。在标题组件中是按钮,它应该使用 changeDark() 函数将主题从 Light 更改为 Dark。所以我的按钮做了我所期望的,但只在 Header 组件中,所以我的意思是,当我点击按钮时,我的主题切换到黑暗,因为函数将 nightTheme 设置为 TRUE,但我需要同时在 FooterComponent 中将 nightTheme 设置为 TRUE我在 HeaderComponent 中点击按钮
        • 更新答案
        • 我已经尝试过您的代码,但不起作用...页脚组件中的 nighTheme 变量仍然设置为 False,而在页眉组件中设置为 True
        • 写得太快了,改函数名:见stackblizstackblitz.com/edit/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-21
        • 1970-01-01
        • 2019-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-12
        相关资源
        最近更新 更多