简体   繁体   English

Angular 2-使用共享服务在组件之间传递数据

[英]Angular 2 - Using shared service pass data between components

My aim is to get the total quantity of my cart items and display it on my Cart link on navbar which is inside my main component. 我的目的是获取购物车项目的总数,并将其显示在主要组件内导航栏上的购物车链接上。

Here is my cart service 这是我的购物车服务

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Observable } from 'rxjs/Rx';

@Injectable()
export class CartService {
    totalQuantity: Number = 0;

    constructor(private _http: Http) { };

    getCartItems(userId) {
        let headers = new Headers({ 'Authorization': 'JWT ' + localStorage.getItem('currentUserToken') });
        let options = new RequestOptions({ headers: headers });
        return this._http.get('http://localhost:3000/cart/getitem/' + userId, options)
            .map((response: Response) => {
                this.totalQuantity = response.json().totalQuantity;
                return response.json();
            })
            .catch(this._handlerError)
    }

    updateCartItem(item){
        console.log(item);
        let headers = new Headers({ 'Authorization': 'JWT ' + localStorage.getItem('currentUserToken') });
        let options = new RequestOptions({ headers: headers });
        return this._http.post('http://localhost:3000/cart/updateitem/', item, options)
            .map((response: Response) => {
                this.totalQuantity = response.json().totalQuantity;
                return response.json();
            })
            .catch(this._handlerError)
    }

    removeCartItem(item){
        let headers = new Headers({ 'Authorization': 'JWT ' + localStorage.getItem('currentUserToken') });
        let options = new RequestOptions({ headers: headers });
        return this._http.post('http://localhost:3000/cart/deleteitem/', item, options)
            .map((response: Response) => {
                this.totalQuantity = response.json().totalQuantity;
                return response.json();
            })
            .catch(this._handlerError)
    }

    _handlerError(err: any) {
        console.log(err);
        // throw err;
        return Observable.throw(err);
    }
}

I made a public variable called totalQuantity and is filled with value after executing one of the cart services functions. 我创建了一个名为totalQuantity的公共变量,并在执行购物车服务功能之一后填充了值。 This totalQuantity variable is accessed by app component. totalQuantity变量由应用程序组件访问。

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

import { loginStatusChanged } from './auth.guard';
import { CartService } from './cart';
import { UserService } from './user';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  title = 'app works!';

  loginStatus: boolean;

  constructor(private _cartService: CartService, private _userService: UserService, private _router: Router){}

  totalQuantity = this._cartService.totalQuantity;

  onLogout(){
    this._userService.logout();
    loginStatusChanged.next(false);
    this._router.navigate(['/login']);
  }

  ngOnInit(){
    this.onLogout();
    loginStatusChanged.subscribe(status => this.loginStatus = status);
  }
}

I think the problem here is: 1. If the user doesn't execute a function from the cartService then the totalQuantity variable will never have a value. 我认为这里的问题是:1.如果用户未从cartService执行函数,则totalQuantity变量将永远没有值。 2. How can I get the value of totalQuantity ONLY IF a user logged in. 2. 在用户登录后才能获取totalQuantity的值。

Can anyone help me solve this problems please? 谁能帮我解决这个问题? I'm stuck. 我被卡住了。

I don't see your app.module.ts, but just to be sure, you need to add in your providers your CartService. 我看不到您的app.module.ts,但是请确保您需要在提供程序中添加CartService。

  1. If the user doesn't execute a function from the cartService then the totalQuantity variable will never have a value. 如果用户未从cartService执行函数,则totalQuantity变量将永远没有值。

No, because you wrote that your totalQuantity is initialize at 0. 不,因为您写道您的totalQuantity初始化为0。

  1. How can I get the value of totalQuantity ONLY IF a user logged in. 仅当用户登录时,如何才能获得totalQuantity的值。

In your sharedService, you can to a function that will get the totalQuantity by checkin if the user is logged in. 在您的sharedService中,您可以使用一个函数,该函数将通过签入(如果用户已登录)来获取totalQuantity。

getTotalQuantity() {
   let isLoggedIn: boolean = methodThatCheckIfLoggedIn();
   if (isLoggedIn) 
      return this.totalQuantity;
   return null;
}

The title, 'using shared service pass data between components' suggests a design problem. 标题“在组件之间使用共享服务传递数据”表明存在设计问题。 If you wish to pass data between components you should probably do so by passing data between components ( @Input & @Output ). 如果希望在组件之间传递数据,则可能应该在组件之间传递数据( @Input@Output )。

Having a shared variable ( totalQuantity ) that is populated by some service methods introduces temporal coupling. 具有某些服务方法填充的共享变量( totalQuantity )会引入时间耦合。 The value is only correct if some other action has occurred before . 该值仅在之前已执行其他操作时才正确。 I suggest that it may be better to make totalQuantity a method that fetches its own value. 我建议使totalQuantity成为一种获取其自身值的方法可能会更好。 If you are worried about the performance cost and a willing to sacrifice consistency then you could cache the value within the method. 如果您担心性能成本并愿意牺牲一致性,则可以在方法中缓存值。

Finally, if you don't want to do any of that, then just call one of the methods that updates totalQuantity from within the AppComponent constructor and then update totalQuantity . 最后,如果您不想执行任何操作,则只需从AppComponent构造函数中调用一种更新totalQuantity的方法,然后更新totalQuantity

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

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