简体   繁体   English

理解为什么导入变量的字符串插值在我的Angular 2应用程序中正常工作

[英]Understanding Why This String Interpolation of an Imported Variable is Working in my Angular 2 App

While making some edits to my Angular 2 app, I was able to get something working BEFORE I assumed it should be working. 在对我的Angular 2应用程序进行一些编辑的同时,在我认为它应该正常工作之前,我能够得到一些工作。 In other words, I'm a little perplexed as to why it's working in it's current configuration. 换句话说,我对它为什么在它的当前配置中工作感到有点困惑。 Specifically, I have an authentication.service that handles my login auth. 具体来说,我有一个authentication.service来处理我的登录身份验证。 And I have both a login component and a chat component, both of which have a private instance of the authentication.service in their respective constructors. 我有一个登录组件和一个聊天组件,它们在各自的构造函数中都有一个authentication.service的私有实例。 What I wanted to do was be able to pass the username from the login functionality down to the chat view, so I could display the logged-in user's username in the chatbox. 我想要做的是能够将用户名从登录功能传递到聊天视图,这样我就可以在聊天框中显示登录用户的用户名。 I've got that working, but, strangely enough, I got it working by adding "this.authenticationService.username = this.model.username;" 我有这个工作,但奇怪的是,我通过添加“this.authenticationService.username = this.model.username;”来实现它。 in the login.component, rather than in the authentication.service. 在login.component中,而不是在authentication.service中。 So I'm perplexed as to how/why the chat.component even has access to that info. 所以我很困惑于chat.component如何/为什么甚至可以访问该信息。 If I remove that one line of code from my login.component, the username will not be passed through to the chat.component. 如果我从login.component中删除那一行代码,则用户名将不会传递给chat.component。 But I never actually import the login component into the chat component, so how is it working as is? 但我从来没有真正将登录组件导入聊天组件,那么它是如何工作的呢? Curious to see if someone can help me understand this. 很想知道是否有人可以帮助我理解这一点。 Here are the files in question. 这是有问题的文件。 First, my authentication.service file: 首先,我的authentication.service文件:

import { ContextMenu } from './../ui/context-menu.component';
import { Router, RouterLinkActive } from '@angular/router';
import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthenticationService {

    username;

    constructor(private http: Http) {}

    login(username: string, password: string) {
        return this.http.post('/api/authenticate', JSON.stringify({ username: username, password: password }))
            .map((response: Response) => {
                // login successful if there's a jwt token in the response
                let user = response.json();
                if (user && user.token) {
                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    localStorage.setItem('currentUser', JSON.stringify(user));
                }
            });
    }


    isAuthenticated() {
        if (localStorage.getItem('currentUser')) {
            //console.log('User successfully authenticated...');
            return true;
        } else {
            // console.log('User is not authenticated...');
            return false;
        }
    }

    logout() {
        // remove user from local storage to log user out
        localStorage.removeItem('currentUser');
        console.log('User successfully logged out');
    }
}

And here's my login.component file: 这是我的login.component文件:

import { UserService } from './../../data/user.service';
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,
        private userService: UserService) { }

    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;
                });
                this.authenticationService.username = this.model.username;
    }

}

Here's my chat.component file: 这是我的chat.component文件:

import { AuthenticationService } from './../../data/authentication.service';
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 {

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

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

        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();
  }

    public getTabId(params): string {
        return 'Chat Room';
    }
}

Lastly, my chat.component.html file looks like this (this is where I'm actually using the string interpolation to display the username in the chat): 最后,我的chat.component.html文件看起来像这样(这是我实际上使用字符串插值来显示聊天中的用户名):

<div class="centered-display" align="center">
  <h3>User: {{authenticationService.username}}</h3>
  <div *ngFor="let message of messages" class="message">
    {{authenticationService.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>

Can someone help me understand why this is working as is? 有人可以帮助我理解为什么这样做是有效的吗? The one line that makes this work is the last line in my login.component login function: "this.authenticationService.username = this.model.username;". 使这项工作的一行是我的login.component登录函数的最后一行:“this.authenticationService.username = this.model.username;”。 But, again, my chat component doesn't have access to my login component (as as I understand). 但是,我的聊天组件再次无法访问我的登录组件(据我了解)。 So why is this working? 那么为什么这样呢?

Your chat component and login component may not directly relate to each other, but they do both have access to the authenticationService . 你的聊天组件和登录的组件可能不直接涉及到对方,但他们都可以访问authenticationService Specifically, they both have a reference to the same instance of that service injected. 具体来说,它们都引用了注入的服务的相同实例。

This means that when you do this.authenticationService.username = this.model.username in your login component, you are setting the username property on the same authenticationService object that you are accessing with your interpolation in the chat component view ( {{authenticationService.username}} ). 这意味着当您在登录组件中执行this.authenticationService.username = this.model.username时,您将在聊天组件视图中使用插值访问的同一authenticationService对象上设置username属性( {{authenticationService.username}} )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM