NG Model

组件传值双向绑定

output绑定事件,由组件绑定事件EventEmitter向父组件传输信息,属性名+属性后缀Change 是约定的固定写法;

// child.component.html

<h1>status in child: {{childStatus}}</h1>
<button (click)="toggle()">Toggle childStatus</button>
// child.component.ts

import {Component,OnInit,Input,Output,EventEmitter} from '@angular/core';
@Component({
  selector: 'test-binding',
  templateUrl: './child.component.html'
})
export class ChildComponent implements OnInit{
  @Input() childStatus;
  @Output() childStatusChange = new EventEmitter();
  ngOnInit(){}

  toggle(){
    this.childStatus = !this.childStatus;
    this.childStatusChange.emit(this.childStatus);
  }
}
// app.component.html
<test-binding [(childStatus)]="parentStatus"></test-binding>
<h1>status in parent: {{parentStatus}}</h1>
<button (click)="toggle()">Toggle parentStatus</button>
// app.component.ts
import { Component,OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  parentStatus: boolean = true;
  ngOnInit(){
    
  }
  toggle(){
    this.parentStatus = !this.parentStatus;
  }
}

https://stackblitz.com/edit/angular-uagcji

监听数据变化 旧值和新值

通过 ngModelChange 和 BehaviorSubject

<hello name="{{ name }}"></hello>
<p>
  Start editing to see some magic happen :)
</p>
<input ngModel (ngModelChange)="value$.next($event)">
<p>Previous value: {{ previousValue }}</p>
<p>Current value: {{ currentValue }}</p>
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  name = 'Angular 5';
  value$ = new BehaviorSubject(null);
  previousValue = null;
  currentValue = null;

  ngOnInit() {
    const pairwise$ = this.value$.debounceTime(200).pairwise();
    pairwise$.subscribe(([prevous, current]) => {
      this.previousValue = prevous;
      this.currentValue = current;
    });
  }
}

https://stackblitz.com/edit/angular-ogetgv?file=index.html

自定义组件使用ngModel

ControlValueAccessor 实现model->view view->model,从而实现的双向绑定
自定义组件需要双向绑定即实现ControlValueAccessor的接口即可
组件需要继承 ControlValueAccessor

<fl-calendar [(ngModel)]=“value" ><fl-calendar/>
import { ControlValueAccessor } from '@angular/forms';
import { Component, OnInit, Input, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

export const CALENDAR_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => Calendar),
    multi: true
};

@Component({
  selector: 'fl-calendar',
  templateUrl: './calendar.component.html',
  styleUrls: [‘./calendar.component.scss'],
  providers: [CALENDAR_VALUE_ACCESSOR]
})
export class CalendarComponent implements OnInit, ControlValueAccessor {

  constructor() { }

  private innerValue: any = '';

  public onModelChange: Function = () => {};
  public onModelTouched: Function = () => {};

  ngOnInit() {}

  set value(v: any) {
    if (v !== this.innerValue) {
      this.innerValue = v;
      this.onModelChange(v); // value更改
    }
  }
  get value(): any {
    return this.innerValue;
  }

  // 获取value值 组件使用 值未改变时,不触发writeValue方法
  writeValue(value: any) {
    if (value !== this.innerValue) {
      this.innerValue = value;
    }
  }

  registerOnChange(fn: any) {
    this.onModelChange = fn;
  }

  registerOnTouched(fn: any) {
    this.onModelTouched = fn;
  }

}

https://serious-lose.notion.site/NG-Model-89fca26e60784903b9b16a7c5b52bdb5

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值