【问题标题】:Behavior Subject Vs. Public?行为主体与。上市?
【发布时间】:2021-07-30 16:11:24
【问题描述】:

我们可以使用 Behavior Subject 访问多个组件中的变量,但我刚刚发现我们可以访问其他组件中的变量,只需在我们希望访问它们的文件的构造函数中将它们声明为“公共”。

行为主体是在组件之间传递变量值的首选方式,还是可以使用 public 代替/使用“public”有什么缺点?

方法一:行为主体

// To use Behavior Subject: 
// First, add the .service's name to the constructor() of both components.
// Next, add this code to your .service file: 
//    //-------------------------------------------------------------------------------
//    public loginPageErrorMessageSource = new BehaviorSubject<any>(null);    // The (null) tells it to initialize the listener to "null"
//    changeLoginPageErrorMessage(message: any) {                             // To change the message / variable value, call this function from one of your .components (you can't call this function from within the same .service file)
//         this.loginPageErrorMessageSource.next(message)
//    }
//    loginPageErrorMessageChanges = this.loginPageErrorMessageSource.asObservable();   
//    -------------------------------------------------------------------------------

然后将其放入您希望访问消息更改的组件的 ngOnInit() 中:

        this.loginPageErrorMessageChanges.subscribe(data => { 
              if(data !== undefined) { 
                     console.log(data) 
              } 
        }) 

方法二:在构造函数中公开文件

-假设我有一个 sign-in.component.ts 文件,我希望访问 change-password.component.ts 中变量的值。

我只是把它放在 change-password.component.ts 的 constructor() 中:

constructor(public signInComponent: SignInComponent) { }

然后在change-password.component.ts的ngOnInit()中打印出来:

ngOnInit() {
   console.log(this.signInComponent.variableIwantToAccess)
}

【问题讨论】:

  • 您能否提供一些示例代码来说明您如何访问组件之间的变量?
  • 我已经更新了我的问题

标签: angular rxjs components behaviorsubject


【解决方案1】:

编辑

你试过了吗?当我尝试这个时,我得到ERROR NullInjectorError: R3InjectorError(AppModule)[SignInComponent -&gt; SignInComponent -&gt; SignInComponent]

SignInComponent 不可注入。

这是我试过的代码:

组件 1

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

@Component({
  selector: 'pm-sign-in',
  templateUrl: './sign-in.component.html',
  styleUrls: ['./sign-in.component.css']
})
export class SignInComponent implements OnInit {
  variableIWantToAccess = "I want this value";

  constructor() { }

  ngOnInit(): void {
  }

}

组件 2

import { Component, OnInit } from '@angular/core';
import { SignInComponent } from '../sign-in/sign-in.component';

@Component({
  selector: 'pm-change-password',
  templateUrl: './change-password.component.html',
  styleUrls: ['./change-password.component.css']
})
export class ChangePasswordComponent implements OnInit {

  constructor(public signInComponent: SignInComponent) { }

  ngOnInit(): void {
    console.log(this.signInComponent.variableIWantToAccess)
  }

}

顺便说一句 - 服务没有使用 BehaviorSubject。它可以只使用服务中的公共属性来与多个组件共享该值。

仅当您希望服务提供推送通知时才需要 BehaviorSubject。

更新: 后续问题要求澄清:

仅当您希望服务提供推送通知时才需要 BehaviorSubject。

如果您想在某处存储一个值(如用户名)并在需要时访问它,您可以在服务中创建一个简单的属性:

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

  userName: string = '';

  constructor() { }
}

并从任何组件访问它:

export class SignInComponent implements OnInit {

  constructor(private service: UserService) { }

  ngOnInit(): void {
    this.service.userName = "New User Name"
  }

}

如果您希望每次值更改时都通知代码,请使用 BehaviorSubject。当您的代码需要对该更改做出反应时,这通常用于用户操作(例如选择下拉选项)。

您可以在此处找到一个 stackblitz 示例:https://stackblitz.com/edit/angular-property-vs-behaviorsubject-deborahk

使用简单的属性,您可以将值放入服务中,然后将其从服务中取出。这对于设置一次然后多次访问的用户名之类的东西很有效。

使用 BehaviorSubject,只要值发生更改,代码就会收到通知。这对于任何更改以及需要通知组件更改的任何内容都很有用,例如用户偏好或订单数量。

【讨论】:

  • “如果您希望服务接收推送通知”是什么意思?
  • 上面说provide推送通知不是receive推送通知。请参阅上面的说明。
  • @DeborahK 我们可以用组件通信来代替推送通知,我认为它更通用
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多