Angular4-在线竞拍应用-组件间通信

angular应用就是一个组件树
要创建松耦合的组件

组件通信的例子

新生成一个项目ng new demo2

或者通过webstorm,File,New,Project..,Angular CLI,然后把项目名改成demo2

因为要用双向绑定,在app.module.ts中添加

import{FormsModule} from '@angular/forms'

imports: [
    BrowserModule,
    FormsModule
  ],

从父组件传递数据到子组件

组件间通信是单向的,从父组件传递到子组件。

新建一个组件ng g component order

修改order.component.ts

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

@Component({
  selector: 'app-order',
  templateUrl: './order.component.html',
  styleUrls: ['./order.component.css']
})
export class OrderComponent implements OnInit {

  @Input()
  stockCode:string;

  @Input()
  amount:number;

  constructor() { }

  ngOnInit() {
  }

}

修改order.component.html

<p>
  我是子组件
</p>
<p>
  买{{amount}}手{{stockCode}}股票
</p>

修改其父组件app,修改app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  stock="";

  title = 'app';
}

修改app.component.html

<div>
  我是父组件
</div>
<div>
  <input type="text" placeholder="请输入股票代码" [(ngModel)]="stock">
  <app-order [stockCode]="stock" [amount]="100" ></app-order>
</div>

组件间通信是单向的,只能从父组件到子组件

启动项目。

子组件的数据传输到父组件

新建一个组件ng g component priceQuote

修改price-quote.component.ts

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

@Component({
  selector: 'app-price-quote',
  templateUrl: './price-quote.component.html',
  styleUrls: ['./price-quote.component.css']
})
export class PriceQuoteComponent implements OnInit {

  stockCode:string="IBM";

  price:number;

  constructor() {
    setInterval(()=>{
      let priceQuote:PriceQuote=new PriceQuote(this.stockCode,100*Math.random())
      this.price=priceQuote.lastPrice;
    },1000)
  }

  ngOnInit() {
  }

}

export class PriceQuote{
  constructor(public stockCode:string,
              public lastPrice:number){

  }
}

修改price-quote.component.html

<div>
  这里是报价组件
</div>
<div>
  股票代码是{{stockCode}},股票价格是{{price|number:'2.2-2'}}
</div>

修改app.component.html

<!--<div>-->
  <!--我是父组件-->
<!--</div>-->
<!--<div>-->
  <!--<input type="text" placeholder="请输入股票代码" [(ngModel)]="stock">-->
  <!--<app-order [stockCode]="stock" [amount]="100" ></app-order>-->
<!--</div>-->


<app-price-quote></app-price-quote>

启动项目

现在我要把子组件中的数据传到父组件

修改price-quote.component.ts

import {Component, OnInit, EventEmitter, Output} from '@angular/core';

@Component({
  selector: 'app-price-quote',
  templateUrl: './price-quote.component.html',
  styleUrls: ['./price-quote.component.css']
})
export class PriceQuoteComponent implements OnInit {

  stockCode: string = "IBM";

  price: number;
  //EventEmitter既可以当被观察者也可以当观察者
  /**
   * 泛型规定的是向外发射的是什么类型的
   * @type {EventEmitter<any>}
   */
  @Output()
  lastPrice: EventEmitter<PriceQuote> = new EventEmitter();

  constructor() {
    setInterval(() => {
      let priceQuote: PriceQuote = new PriceQuote(this.stockCode, 100 * Math.random())
      this.price = priceQuote.lastPrice;
      this.lastPrice.emit(priceQuote);//用emit向外发射
    }, 1000)
  }

  ngOnInit() {
  }

}

export class PriceQuote {
  constructor(public stockCode: string,
              public lastPrice: number) {

  }
}

修改app.component.ts

import { Component } from '@angular/core';
import {PriceQuote} from "./price-quote/price-quote.component";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  stock="";

  priceQuote:PriceQuote=new PriceQuote("",0);

  priceQuoteHandler(event:PriceQuote){//接收子组件传递过来的数据
    this.priceQuote=event;
  }
}

修改app.component.html

<!--<div>-->
<!--我是父组件-->
<!--</div>-->
<!--<div>-->
<!--<input type="text" placeholder="请输入股票代码" [(ngModel)]="stock">-->
<!--<app-order [stockCode]="stock" [amount]="100" ></app-order>-->
<!--</div>-->


<app-price-quote (lastPrice)="priceQuoteHandler($event)"></app-price-quote>

<div>
  这是在报价组件外部,
<div>

</div>
  股票代码是{{priceQuote.stockCode}},
  股票价格是{{priceQuote.lastPrice|number:'2.2-2'}}
</div>

启动项目

其中price-quote.component.ts

/**
EventEmitter既可以当观察者也可以当被观察者
其中泛型规定的是向外发射的是什么类型的
*/
@Output()
lastPrice: EventEmitter<PriceQuote> = new EventEmitter();

this.lastPrice.emit(priceQuote);//用emit方法向外发射

其中在app.component.html中

<app-price-quote (lastPrice)="priceQuoteHandler($event)"></app-price-quote>

默认情况下里边的lastPrice要和price-quote.component.ts中的lastPrice一样。

如果想不一样的话可以

@Output('priceChange')
lastPrice: EventEmitter<PriceQuote> = new EventEmitter();


<app-price-quote (priceChange)="priceQuoteHandler($event)"></app-price-quote>

现在这种情况只能由其父组件来绑定事件并处理。如果两个组件不存在父子关系,怎么以一种松耦合的方式传递数据呢?

中间人模式

中间人组件负责从一个组件接受数据并传递给另一个组件。

修改price-quote.component.html

<div>
  这里是报价组件
</div>
<div>
  股票代码是{{stockCode}},股票价格是{{price|number:'2.2-2'}}
</div>

<div>
  <input type="button" value="立即购买" (click)="buyStock($event)">
</div>

在price-quote.component.ts中添加

  @Output()
  buy:EventEmitter<PriceQuote>=new EventEmitter();

  buyStock(event){
    this.buy.emit(new PriceQuote(this.stockCode,this.price));
  }

修改app.component.html


<app-price-quote (buy)="buyHandler($event)"></app-price-quote>

<app-order [priceQuote]="priceQuote"></app-order>

修改app.component.ts

export class AppComponent {

  //stock="";

  priceQuote:PriceQuote=new PriceQuote("",0);

  buyHandler(event:PriceQuote){
    this.priceQuote=event;
  }
}

修改order.component.ts

export class OrderComponent implements OnInit {

  @Input()
  priceQuote:PriceQuote;

  constructor() { }

  ngOnInit() {
  }

}

修改order.component.html

<p>
  我是下单组件
</p>
<p>
  买100手{{priceQuote.stockCode}}股票,买入价格是{{priceQuote.lastPrice | number:'2.2-2'}}
</p>

priceQuote组件通过app组件这个中间人把数据传给order组件。

app是priceQuote和order这两个兄弟组件的父组件。

如果没有父组件这种关系,可以定义一个服务来做实现中间人的功能。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值