应用程序组件的公共变量Angular2

时间:2017-02-04 19:25:12

标签: angular typescript global public

在我的Angular2应用程序中,我有一个“目录”和一个“购物车”,它通过目录组件+目录服务和购物车组件+购物车服务在我的代码中表示。

我的Catalog组件中有一系列产品,我想将数组中的项添加到另一个(最初是空的)数组,即Cart数组。

我的目录组件代码:

import { Component, OnInit } from '@angular/core';
import { CatalogService } from './catalog.service';
import { CartComponent } from '../cart/cart.component';//I want to use the "cart" array initialized there in the Cart Component 

@Component({
  selector: 'catalog',
  templateUrl: './catalog.component.html',
 styleUrls: ['./catalog.component.scss']
})

export class CatalogComponent implements OnInit {
    catalog: any;
    image: any;
    title: string;
    description: string;
    prod: any;
    visible: boolean;

constructor(public catalogService: CatalogService){ } 

ngOnInit(){

    this.catalogService.getCatalogItems().subscribe(
        (data) => this.catalog = data
    );
}

getPrev(){
    this.catalog.push(this.catalog[0]);
    this.catalog.shift();
}

getNext(){
    this.catalog.unshift(this.catalog[this.catalog.length-1]);
    this.catalog.pop();
}

 togglePopup(prod){
    this.prod = prod;
    this.visible = !this.visible;
    this.image = prod.image;
    this.title = prod.title;
    this.description = prod.description;
}

   toCart(prod){
     this.cart.push(prod);//"cart" array of my Cart Component
   }

}

我的购物车组件:

import { Component, OnInit } from '@angular/core';
import { CartService } from './cart.service';

@Component({
    selector: 'cart',
    templateUrl: './cart.component.html',
    styleUrls: ['./cart.component.scss']
})

export class CartComponent implements OnInit {

    constructor (private cartService: CartService, public cart: Cart[]){}//by "public cart: Cart[]" I make it available from anywhere in my app

    ngOnInit(){
        this.cartService.getCartItems();
    }
}

我的目录服务:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

import 'rxjs/add/operator/map';

@Injectable()
export class CatalogService {
    constructor(private http: Http){ }

  getCatalogItems() {
      return this.http.get('../catalog.json')//there are some items in the "catalog.json"
      .map((res) => res.json())
  }
}

我的购物车服务:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

import 'rxjs/add/operator/map';

@Injectable()
export class CartService {
   constructor(private http: Http){ }

  getCartItems() {
      return this.http.get('../cart.json')//there are no items initially in the "cart.json", I want to add items from Catalog array to the initialized "cart : Cart[]" array
      .map(
        (res) => res.json()
      );
  }
}

虽然我在购物车组件中宣布了全局购物车变量(“公共购物车:购物车[]”)并将购物车组件导入目录组件,但购物车变量在那里(在我的目录组件中)不存在,我无法从我的目录中将项目添加到购物车。

那么,如何创建一个适用于整个应用的购物车阵列?如果我添加/删除smth,我想要其他组件,我会使用购物车对象自动更新其实例。

2 个答案:

答案 0 :(得分:1)

传递给构造函数的参数是实例值。您需要该类的实例才能访问它们。导入在这里根本没用。

将值移至服务并将服务注入您要访问该值的位置。

仅提供一次服务(@NgModule() AppComponent),然后应用程序中的每个组件和服务都将获得注入的相同服务实例。

另见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

答案 1 :(得分:1)

在构造函数参数上放置publicprivateprotectedreadonly修饰符是语法简写,用于声明具有相同名称和修饰符的属性并指定它在实例化类时,为该参数传递给构造函数的值。

这些修饰符是一种创建实例成员的方法。它们不会影响全局范围,它们的影响实际上是在类实例级别确定的。

例如,以下两个类定义完全等效

1

class A {
  constructor(m: number) {
    this.m = m;
  }
  readonly m: number;
}

2

class A {
  constructor(readonly m: number) { }
}

要实现全局效果,您需要执行类似

的操作
export class CartComponent {

  constructor (private cartService: CartService, cart: Cart[]) {
    window.cart = cart; // Make cart available from anywhere in my app.
  }
}
declare global {
  interface Window {
    cart: Cart[];
  }
}

但请不要这样做! 不要使用全局变量!

您可以使用角度服务,但无论您使用何种框架,都有更多直接选项。

例如

应用/共享state.ts

export default { 
  cart: undefined,
  // other shared stuff...
};

应用/ cart.component.ts

import sharedState from 'app/shared-state';

export class CartComponent {

  constructor (private cartService: CartService, public cart: Cart[]) {
    sharedState.cart = cart;
  }
}

这仍然是共享的可变状态,应该避免,但它不会污染全局命名空间。

GünterZöchbauer的回答可能更接近你正在寻找的东西,因为你似乎正在编写一个有角度的应用程序,这将是传统方法。

我想回答具体问题,并澄清与参数属性语法相关的任何误解,这不是特定于角度的。