【问题标题】:How to pass multiple(2 or many) variables through behaviour subject in angular如何通过角度的行为主题传递多个(2个或多个)变量
【发布时间】:2017-12-01 16:59:39
【问题描述】:

我是 rxjs 的新手。在我的应用程序中,我遇到了将用户名和密码值从一个组件传递到另一个组件的情况(角度)。请您帮助我通过行为主题通过一个简洁的基本示例将这些变量从一个组件传递到另一个组件。 我有一个存储用户详细信息的类 UserInformation.ts如下

export class UserInformation {
    username: string;
    constructor() {
    }
}

我有如下服务。 用户信息.service.ts

import { Injectable } from '@angular/core';
import { UserInformation } from '../UserInformation';
@Injectable()
export class UserInformationService {
  userData:UserInformation;
  variable:string='ServiceVariable';
  constructor() {
    this.userData = new UserInformation(); 
   }
  getUserData()
  {
    return this.userData;
  }
  setUserData(userData:UserInformation)
  {
    this.userData.username=userData.username;
    console.log(this.userData.officeLocation);
  }
}

在我的 FirstComponent.ts 中有以下代码。此 getVALuesFromForm 方法用于从表单中获取用户名。

getValuesFromForm()
   {
     this.enteredUser.username = this.loginform.get('Username').value;
     console.log(this.enteredUser.username);
     this.service.setUserData(this.enteredUser);     
   }

在我的 secondComponent.ts 中,我有以下代码。

import { Component, OnInit , Input , Output  } from '@angular/core';
import { UserInformation } from '../UserInformation';
import  { UserInformationService }   from '../services/user-information.service';
import { Injectable } from '@angular/core';
@Component({
  selector: 'app-nav-bar-component',
  templateUrl: './nav-bar-component.component.html',
  styleUrls: ['./nav-bar-component.component.css'],
  providers:[UserInformationService]
})
@Injectable()
export class NavBarComponentComponent implements OnInit {
   userInfo:UserInformation;    
  constructor(public service:UserInformationService) {
    this.userInfo=service.getUserData();
    console.log(service.userData.username);
    console.log(this.userInfo.username);
   }
  ngOnInit() {
  }
}

现在我的问题是我们如何借助 Rxjs 中的 Behavior Subject 将这些变量从第一个组件传递到第二个组件

【问题讨论】:

  • 在第一个组件中调用 setUserData 时是否出现错误?
  • 问题在于,您的两个组件都获得了单独的服务实例。您正在实例 1 中设置值并从实例 2 中获取值

标签: angular rxjs angular5


【解决方案1】:

有如下属性的接口,

export interface School {
    teacher: Teacher;
    student?: Student;
}

private emitter = new Subject<School>();

this.emitter.next({ student: ramStudent, teacher: Anieteacher});

【讨论】:

  • 这部分没问题。现在让我们来看一个示例代码。我将添加一些示例代码,以便我能更清楚。
  • Aravind 如果您不介意,请查看代码并告诉我应该如何进行。
  • 您可以在 teamviewer 中使用吗?
  • 不,我没有。我没空
  • 我不明白你能详细说明
【解决方案2】:

为什么你的用例需要 RxJS?

在 Angular 文档中阅读如何在组件之间进行通信: https://angular.io/guide/component-interaction

如果您不需要提供初始值,则可以仅使用主题。

一种可能性是通过服务来实现这一点:

export interface ICredentials {
    username: string;
    password: string;
}

@Injectable()
export class UserService {
    private credentials$ = new BehaviorSubject<ICredentials>({
        username: "initial username",
        password: "initial password"
    });

    constructor() {
    }

    public getCredentials(): Observable<ICredentials> {
        return this.credentials$;
    }

    public setCredentials(credentials: ICredentials) {
        this.credentials$.next(credentials);
    }
}

@Component({
    selector: 'dog',
    template: '<div>Bark: Wuff Wuff {{credentials | json}}</div>'
})
export class DogComponent implements OnDestroy {
    private credentials: ICredentials;
    private credentialsSubscription: Subscription;

    constructor(private userService: UserService) {
        this.credentialsSubscription = this.userService.getCredentials().subscribe(credentials => this.credentials = credentials);
    }

    public ngOnDestroy() {
        this.credentialsSubscription && this.credentialsSubscription.unsubscribe();
    }
}

@Component({
    selector: 'user',
    template: '<div>The User ...</div>'
})
export class UserComponent {
    private credentials: ICredentials = {
        username: "my users username",
        password: "my users password"
    };

    constructor(private userService: UserService) {
    }

    public shoutCredentials() {
        this.userService.setCredentials(this.credentials);
    }
}

您也可以像这样与组件进行通信:

@Component({
    selector: 'information-message',
    template: '<div>My message</div>'
})
export class InformationMessageComponent {
    @Output() public message: EventEmitter<string> = new EventEmitter<string>();
    private myMessage = "Hello World";

    constructor() {}

    public emitMessage() {
        this.message.emit(this.myMessage);
    }
}



@Component({
    selector: 'user',
    template: '<div>Did get message: {{theMessage}}</div> <information-message (message)="onMessage($event)"></information-message>'
})
export class InformationMessageComponent {
    public theMessage: string;

    constructor() {}

    public onMessage(message: string) {
        this.theMessage = message;
    }
}

【讨论】:

  • 这会容易得多,如果你能解释你试图实现的目标。就像一个用户故事。
  • 您建议使用 observables 的代码在我尝试打印时返回空值。
  • 我确实编辑了代码,再试一次,这样会更清楚发生了什么
  • 请您在 plunker 中执行并给我链接。我已经尝试了很长时间,但仍然得到空值。
【解决方案3】:

在组件 1 中,您可以执行以下操作:

export class FirstComponent
{
    username:string = "Some Name";
    age:number = "Some Age";
    obs = new Rx.BehaviourSubject();
    obs.next({username: this.username, age: this.age});
}

在您的组件 2 中,您可以这样做:

export class SecondComponent
{
    constructor(private fc: FirstComponent)
    secondComponentUsername:string;
    secondComponentAge:number;
    subscription = this.fc.obs().subscribe((response) => {
         this.secondComponentUsername = response.username;
         this.secondComponentAge = response.age;
    })
}

【讨论】:

  • 这是你必须做的最基本的事情。如果您需要解释,请告诉我:)
  • Vinod 这里的响应是什么??
  • 响应将是 {username: this.username, age: this.age}
  • 订阅中的第一个方法是在执行 obs.next() 时调用的方法
  • 通过查看许多帖子,我观察到他们正在通过服务传递变量。我也在做同样的事情,但我能够将值从第一个组件设置为服务,并且我在控制台中显示它以进行确认。现在,当我在其他组件中调用 getDAta 时,它显示服务变量未定义。
猜你喜欢
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多