Angular2 组件(页面)之间如何传值
2017-05-23 本文已影响632人
SevenLonely
组件有两种方式将数据传递:“属性绑定”和“事件绑定”。
在Angular 2中,数据和事件变化检测从上到下发生从<b>父级到子级。</b>
Angular 2事件,我们可以使用DOM事件传递模型,其中事件<b>从下到上从子到父。</b>
因此,当涉及可撤消事件传播时,Angular 2事件可以像普通HTML DOM事件一样对待。
<b>@Input()</b>装饰器定义了一组可以<b>从父组件传递的参数。</b>
例如,我们可以修改HelloComponent组件,以便name可以由父提供。
//HelloComponent
import { Component, Input } from '@angular/core';
@Component({
selector: 'rio-hello',
template: '<p>Hello, {{name}}!</p>',
})
export class HelloComponent {
@Input() name: string;
}
//appComponent
import {Component} from '@angular/core';
@Component({
selector: 'app',
template: `<div>
<hello [name]="helloName"></hello>
<hello name="beijing"></hello>
</div>`
})
export class App {
helloName: string;
constructor() {
this.helloName = "World";
}
}
执行结果如下
执行后展示的形态<b>@outputs</b> 从组件发送数据,它接受组件<b>向其父组件公开的输出参数的列表。</b>
app/counter.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'rio-counter',
templateUrl: 'app/counter.component.html'
})
export class CounterComponent {
@Input() count = 0;
@Output() result = new EventEmitter<number>();
increment() {
this.count++;
this.result.emit(this.count);
}
}
app/counter.component.html
<div>
<p>Count: {{ count }}</p>
<button (click)="increment()">Increment</button>
</div>
app/app.component.ts
import { Component, OnChange } from '@angular/core';
@Component({
selector: 'rio-app',
templateUrl: 'app/app.component.html'
})
export class AppComponent implements OnChange {
num = 0;
parentCount = 0;
ngOnChange(val: number) {
this.parentCount = val;
}
}
app/app.component.html
<div>
Parent Num: {{ num }}<br>
Parent Count: {{ parentCount }}
<rio-counter [count]="num" (result)="ngOnChange($event)">
</rio-counter>
</div>
执行结果如下
执行结果@input + @output 绑定定义组件的公共API。在我们的模板中,我们使用 [方括号] 传递输入,使用(括号)来处理输出。
组件的要点不仅是封装,而且是可重用性。<b>@Input()</b>允许我们配置组件的特定实例。
<!-- 绑定到原始字符串 -->
<rio-hello name="World"></rio-hello>
<!-- 绑定到父作用域 -->
<rio-hello [name]="helloName"></rio-hello>
<b>@outputs</b> 从组件发送数据,请先定义outputs属性。它接受组件向其父组件公开的输出参数的列表。
关于双向绑定
双向数据绑定使用ngModel指令将输入和输出绑定组合为单个符号。
<input [(ngModel)]="name" >
//它幕后做的相当于
<input [ngModel]="name" (ngModelChange)="name=$event">
要创建一个支持双向绑定的组件,你必须定义一个@Output属性匹配@Input,但后缀为Change
app/counter.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'rio-counter',
templateUrl: 'app/counter.component.html'
})
export class CounterComponent {
@Input() count = 0;
@Output() countChange = EventEmitter<number>();
increment() {
this.count++;
this.countChange.emit(this.count);
}
}
app/counter.component.html
<div>
<p>
<ng-content></ng-content>
Count: {{ count }} -
<button (click)="increment()">Increment</button>
</p>
</div>
app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'rio-app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
number1: number;
number2: number;
number3: number;
number4: number;
constructor() {
this.number1 = 0;
this.number2 = 0;
this.number3 = 0;
this.number4 = 0;
}
onCountChanged(value: number) {
this.number3 = value;
this.number4 = value;
}
}
app/app.module.ts
import { NgModule } '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CounterComponent } from './counter.component';
@NgModule({
imports: [BrowserModule],
declarations: [
AppComponent,
CounterComponent
],
exports: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}
运行结果如下
运行结果<h6 align = "right">Sivona</h6>