Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular 自定义双向绑定 #2

Closed
PolluxLee opened this issue Apr 7, 2018 · 0 comments
Closed

Angular 自定义双向绑定 #2

PolluxLee opened this issue Apr 7, 2018 · 0 comments

Comments

@PolluxLee
Copy link
Owner

PolluxLee commented Apr 7, 2018

Requirement

We often use two-way data binding like this:

<input class="form-control" [(ngModel)]="value" />

But sometimes we want to use like these:

<input class="form-control" [(value)]="value" />
<input class="form-control" [(content)]="value" />
<input class="form-control" [(hello)]="value" />

Via getter and setter

child.component.html

<p>{{master}}</p>

child.component.ts

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

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

  _master: number = 0;
  @Output() masterChange = new EventEmitter();

  get master() { return this._master; }

  @Input()
  set master(m) {
    this.masterChange.emit(m);
    this._master = m;
  }

  ngOnInit() { }

  add() { this.master++; }
  sub() { this.master--; }
}

parent.component.html

<p>子组件的值 <app-child #child [(master)]="master"></app-child></p>

<p>变更子组件的值 <button (click)="child.sub()"></button>
<button (click)="child.add()"></button></p>

<p>父组件的值 {{master}}</p>

<p>变更父组件的值 <button (click)="sub()"></button>
<button (click)="add()"></button></p>

parent.component.ts

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

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

  master: number = 0;

  constructor() { }

  ngOnInit() { }

  add() { this.master++; }
  sub() { this.master--; }
}

使用 getter 和 setter 要通过一个中间变量 _master 操作。对于 child 组件来说,模板通过 getter 获取 _master 进行显示,master 的值发生变化时会调用 setter,用新的值更新 _master 的值;

对于 parent 组件来说,子组件中 @Input() 装饰器标记 master (可以标记在 getter 也可标记在 setter,只要是标记你要接收的数据即可),用于接收来自父组件的单向绑定,@Output() 装饰器标记 masterChange 向父组件发射数据(注:如果父组件要使用 [(master)] 双向绑定,则一定要命名为 masterChange);

所以当 child 中的 master 值发生变更时,会做两件事:1,更新旧的 _master 值,使得模板中的 master 从 getter 中读取的 _master 是最新的,2,向父组件发射数据,使得和子组件的值同步,达到双向绑定的效果

Demo

stackblitz.com

References

blog.thoughtram.io

@PolluxLee PolluxLee changed the title Angular Custom-Two-Way-Bind Angular Custom Two-way Data Binding Apr 7, 2018
@PolluxLee PolluxLee changed the title Angular Custom Two-way Data Binding Angular 自定义双向绑定 Aug 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant