将“用户名”值从一个组件传递到Angular 2中的另一个组件

时间:2017-01-05 18:51:39

标签: javascript angular typescript socket.io

我理解如何在Angular 2中的父组件中嵌套子组件。这很容易实现。但是我有点不清楚如何将一个值从一个组件传递到另一个组件。在我的用例中,我想将用户名从登录组件传递到聊天组件 - 以便用户名将显示在聊天框中。这就是我需要做的。我理解@Input()装饰器可能在这里使用,我不清楚如何使用它实际传递值。

这就是我在登录组件html中的内容:

<div class="center-box">
        <form name="form" class="form-fields" (ngSubmit)="f.form.valid && login()" #f="ngForm" novalidate>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
                <input type="text" form autocomplete="off" class="form-control" name="username" [(ngModel)]="model.username" #username="ngModel" required />
                <div *ngIf="f.submitted && !username.valid" class="help-block">Username is required</div>
            </div>
            <div class="form-group" [ngClass]="{ 'has-error': f.submitted && !password.valid }">
                <input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel" required />
                <div *ngIf="f.submitted && !password.valid" class="help-block">Password is required</div>
            </div>
            <div class="form-group">
                <button class="submit-btn">Login</button>
            </div>
        </form>
        <div align="center" [ngStyle]="{'color': 'red'}"><alert></alert></div>
    </div>

我的登录组件如下所示:

import { AuthenticationService } from './../../data/authentication.service';
import { AlertService } from './../../data/alert.service';
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';

@Component({
    selector: 'app-login',
    templateUrl: 'app/views/login/login.component.html',
    styleUrls: ['app/views/login/login.component.css']
})

export class LoginComponent implements OnInit {

    model: any = {};
    loading = false;
    username;
    password;

    constructor(
        private router: Router,
        private authenticationService: AuthenticationService,
        private alertService: AlertService) { }

    ngOnInit() {
        // reset login status
        this.authenticationService.logout();
    }

    login() {
        this.loading = true;
        this.authenticationService.login(this.model.username, this.model.password)
            .subscribe(
                data => {
                    this.router.navigate(['/']);
                    console.log('User logged in as: ' + this.model.username);
                },
                error => {
                    this.alertService.error(error);
                    this.loading = false;
                });
    }
}

我的聊天组件html如下所示:

<div class="centered-display" align="center">
  <h3>User: {{username}}</h3>
  <div *ngFor="let message of messages" class="message">
    {{username}}: {{message.text}}
  </div>
  <input class="form-group" [(ngModel)]="message" (keypress)="eventHandler($event)">
  <div class="spacing">
    <button class="submit-btn" md-button (click)="sendMessage()">SEND</button>
  </div>
</div>

这是聊天组件文件:

import { Router, ActivatedRoute } from '@angular/router';
import { ChatService } from './chat.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { TabPage } from '../../ui/tab-navigation/tab-page';

@Component({
  templateUrl: './chat.component.html',
  styleUrls: ['./chat.component.less']
})
export class ChatComponent extends TabPage implements OnInit, OnDestroy {

  username = '';
  messages = [];
  users = [];
  routes;
  connection;
  userbase;
  route;
  message;
  user;

  constructor(private chatService:ChatService, router: Router, route: ActivatedRoute) {

        super(router, route);

        this._title = 'Chat Room';

        this.addEventListener('paramsChange', function(params) {

            this._title = 'Chat Room';

        }.bind(this));
   }

  sendMessage() {
    this.chatService.sendMessage(this.message);
    this.message = '';
  }

  sendUser() {
    this.chatService.sendUser(this.user);
    this.user = '';
  }

    trackUser() {
    this.chatService.trackUser(this.route);
    console.log('A user just navigated to ' + this.route);
  }

  // For when user clicks "enter/return" to send message
  eventHandler(event: KeyboardEvent): void {
    if (event.key === 'Enter') {
        this.chatService.sendMessage(this.message);
        this.message = '';
    }
  }

  ngOnInit() {
    this.connection = this.chatService.getMessages().subscribe(message => {
      this.messages.push(message);
    });
    this.userbase = this.chatService.getUsers().subscribe(user => {
      this.users.push(user);
    });
    this.routes = this.chatService.getRoutes().subscribe(route => {
      this.routes.push(route);
    });
  }

  ngOnDestroy() {
    this.connection.unsubscribe();
    this.userbase.unsubscribe();
  }

}

所以基本上归结为我如何传递h3在聊天组件视图中的值:

用户:{{username}}

。如何绑定login-component中的用户名值,并将其传递到聊天组件中?

2 个答案:

答案 0 :(得分:2)

共享服务可能是最好的:制作新服务:

@Injectable()
export class YourSharedService {
    sharedUser: {
        // your properties here... e.g
        username: 'string'
    };
}

然后将它注入父级和子级的构造函数中,并在组件中访问它:

constructor(private yourSharedService: YourSharedService......) {  }

在您的登录组件中,您可以将用户分配给新创建的服务,以便您可以在注入共享服务的所有组件中访问它:

分配:this.yourSharedService.sharedUser = yourUserObject

然后您可以访问组件中的用户:

localUserObject = this.yourSharedService.sharedUser;

其他一些信息:当您的子组件不在不同的路径后面时,@Input可以正常工作。当您的子组件位于子路由中时,可以使用共享服务:)

共享服务是双向的,当您在一个组件中更改用户属性并将用户存储在共享服务中时,共享同一对象(或其他)的其他组件会自动获取当前信息,例如您将路由到另一个已实现共享服务的组件。

答案 1 :(得分:1)

您应该设置一个单独的用户服务,在登录后存储用户信息。然后,您可以将用户服务(确保使用@Injectable()装饰器实际注入其中)注入聊天组件(通过构造函数:constructor(public userService: UserService))并在模板中引用它:{{1} }。