Input至關於指令的值綁定,不管是單向的(@)仍是雙向的(=)。丟失將父做用域的值「輸入」到子做用域中, 而後子做用域進行相關處理。css
Output 至關於指令的方法綁定,子做用域觸發事件執行響應函數, 而響應函數方法體則位於父做用域中, 至關於將事件「輸出」到父做用域中, 在父做用域中處理。 html
看個angular2示例吧,咱們自定義一個numberInput component,獲取父做用域的值或者屬性,而後在鼠標離開的時候調用父組件的方法驗證angular2
import { Component, Input, Output, OnInit, ExistingProvider, forwardRef, AfterViewInit, ElementRef, ViewChild, ViewContainerRef, ChangeDetectorRef, Optional, EventEmitter } from '@angular/core' import { NgModel, ControlValueAccessor, NG_VALUE_ACCESSOR, NgForm, FormControl, ValidatorFn, ValidationErrors } from '@angular/forms' import { InputBase, existingProvider } from '../../inputBase' import { Observable } from 'rxjs' declare var $: any; @Component({ selector: 'cm-number', templateUrl: 'numberInput.component.html', styleUrls: ["./numberInput.component.css"], providers: [existingProvider(NumericInputComponent)] }) export class NumericInputComponent extends InputBase implements OnInit { @ViewChild("input") input: ElementRef; ngOnInit() { Observable.merge( Observable.fromEvent<Event>(this.input.nativeElement, "input"), Observable.fromEvent<Event>(this.input.nativeElement, "blur"), Observable.fromEvent<Event>(this.input.nativeElement, "change") ).subscribe(e => { e.stopPropagation(); e.stopImmediatePropagation(); let p = e.target as HTMLInputElement; let val = this.format(p.value); if (val !== p.value) { p.value = val; } if (val != this.model.value) { if (val == undefined || val.trim() === "") { this.onChange(undefined); } else { this.onChange(parseFloat(val)); } } }); if (this.model != null) { var fn: ValidatorFn = (c) => { var errors: ValidationErrors = {}; if ((this.hasEqualOperatorForMin && parseFloat(this.internalValue) < parseFloat(this.min.toString())) || (!this.hasEqualOperatorForMin && parseFloat(this.internalValue) <= parseFloat(this.min.toString())) || parseFloat(this.internalValue) > parseFloat(this.max.toString())) { errors.dose = true; } return errors; } this.model.control.setValidators(fn); } } private get internalValue() { let val = (<HTMLInputElement>this.input.nativeElement).value; if (!val) return undefined; val = val.trim(); if (val == "") return undefined; return val; } private format(val: string) { while (true) { let newVal = val.replace(/[^0-9.-]/g, ''); if (this.allowFloat) { newVal = newVal.replace(/(\..*)\./g, '$1'); } else { newVal = newVal.replace(/(.*)\./g, '$1'); } if (!this.allowNegative) { newVal = newVal.replace(/-/g, ''); } else { newVal = newVal.replace(/^-(-.*)/g, '$1'); newVal = newVal.replace(/(.+)-/g, '$1'); } newVal = newVal.replace(/^0+([0-9].*)/g, '$1'); newVal = newVal.replace(/^0+(0\..*)/g, '$1'); if (newVal === val) break; val = newVal; } return val; } public _value: string; @Input() maxlength: number; @Input() readonly: boolean = false; @Input() allowFloat: boolean = true; @Input() min: number = 0; @Input() max: number = 99999; @Input() public get value() { return this._value; } public set value(val: string) { this._value = val; if (val == undefined || val.trim() == "") { this.onChange(undefined); } else { this.onChange(parseFloat(this._value)); } } public writeValue(obj: any) { obj = obj == undefined ? "" : obj; (this.input.nativeElement as HTMLInputElement).value = obj; } @Output() public onblur: EventEmitter<any> = new EventEmitter<any>(); blur(e: Event) { this.onblur.emit($(e.target).val()); } }
就舉一個例子:ide
咱們在父做用域中使用的時候, 能夠這樣賦值:函數
其實number input component 中, 咱們會根據 allowFloat 的值,來決定是否容許輸入小數。this
ok, 以上是Input的示例。spa
Output通常都是一個EventEmitter的實例,使用實例的emit方法將參數emit到父組件中,觸發父組件的事件。3d
而後父組件監聽到該事件的發生,執行對應的處理函數。code
這裏之因此要自定義一次 blur 事件(EventEmitter), 是由於在 ngOnInit()中已經對blur 事件作過處理,這樣父控件中就會被阻止掉,若是父控件中要用到blur 事件的話, 就能夠用這種方式來作,咱們自定義一個叫onBlur 的事件,而後在父控件中去實現內部邏輯。component
是否是很簡單啊。