如何在角度2的组件之间使用双向数据绑定? [英] How to use two way data binding between components in angular 2?

查看:65
本文介绍了如何在角度2的组件之间使用双向数据绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我创建了一个User类:

export class User {
  name: string;
  email: string;
}

然后我得到了CoreComponent,它使用FormInputComponent并从User类创建了public user:

import {Component} from 'angular2/core';
import {FormInputComponent} from '../form-controls/form-input/form-input.component';
import {User} from '../core/user';

@Component({
  selector: 'core-app',
  templateUrl: './app/assets/scripts/modules/core/core.component.html',
  styleUrls: ['./app/assets/scripts/modules/core/core.component.css'],
  directives: [FormInputComponent]
})

export class CoreComponent {
  public user: User = {
    name: '',
    email: ''
  }
}

然后,我创建了一个输入组件,这是一个可重复使用的输入组件,它将以模型值作为输入,并在进行更改时导出新值,以便CoreComponent可以使用新的模型更新模型.值:

import {Component, Input, Output, EventEmitter, DoCheck} from 'angular2/core';

@Component({
  selector: 'form-input',
  templateUrl: './app/assets/scripts/modules/form-controls/form-input/form-input.component.html',
  styleUrls: ['./app/assets/scripts/modules/form-controls/form-input/form-input.component.css'],
  inputs: [
    'model',
    'type',
    'alt',
    'placeholder',
    'name',
    'label'
  ]
})

export class FormInputComponent implements DoCheck {
  @Input() model: string;
  @Output() modelExport: EventEmitter = new EventEmitter();

  ngDoCheck() {
    this.modelExport.next(this.model);
  }
}

CoreComponent的模板使用两个FormInputComponent并传递user.nameuser.email作为它们的输入:

<form-input [model]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [model]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>

FormInputComponent模板:

<div>
  <label attr.for="{{name}}">{{label}}</label>
  <input [(ngModel)]="model" type="{{type}}" placeholder="{{placeholder}}" alt="{{alt}}" id="{{name}}">
</div>
<pre>{{model}}</pre>

现在的问题是,我只能看到位于FormInputComponent模板内的pre元素的更改,但是父级CoreComponentpre元素保持不变.

我查看了这个问题处于我要实现的目标范围之内,但由于使用服务仅返回层次结构中的一个值而不能完全解决,如果您在同一页面上有多个FormInputComponent,这似乎有点过头了,而且有点混乱.

所以我的问题很简单,如何将模型传递给FormInputComponent并让它在值更改时返回新值,以便CoreComponent中的public user自动更改?

解决方案

要在使用组件时能够短时使用双向绑定,您需要将输出属性自述为modelChange:

export class FormInputComponent implements DoCheck {
  @Input() model: string;
  @Output() modelChange: EventEmitter = new EventEmitter();

  ngDoCheck() {
    this.modelChange.next(this.model);
  }
}

并以这种方式使用它:

<form-input [(model)]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [(model)]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>

First I've created a User class:

export class User {
  name: string;
  email: string;
}

Then I've got my CoreComponent which uses the FormInputComponent as well as creating a public user from the User class:

import {Component} from 'angular2/core';
import {FormInputComponent} from '../form-controls/form-input/form-input.component';
import {User} from '../core/user';

@Component({
  selector: 'core-app',
  templateUrl: './app/assets/scripts/modules/core/core.component.html',
  styleUrls: ['./app/assets/scripts/modules/core/core.component.css'],
  directives: [FormInputComponent]
})

export class CoreComponent {
  public user: User = {
    name: '',
    email: ''
  }
}

Then I've created an input component, which is a re-useable input component that will take a model value as an input and when changes are made export the new value so that CoreComponent can update the model with the new value:

import {Component, Input, Output, EventEmitter, DoCheck} from 'angular2/core';

@Component({
  selector: 'form-input',
  templateUrl: './app/assets/scripts/modules/form-controls/form-input/form-input.component.html',
  styleUrls: ['./app/assets/scripts/modules/form-controls/form-input/form-input.component.css'],
  inputs: [
    'model',
    'type',
    'alt',
    'placeholder',
    'name',
    'label'
  ]
})

export class FormInputComponent implements DoCheck {
  @Input() model: string;
  @Output() modelExport: EventEmitter = new EventEmitter();

  ngDoCheck() {
    this.modelExport.next(this.model);
  }
}

The CoreComponent's template uses two FormInputComponents and passes user.name and user.email as the input for them:

<form-input [model]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [model]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>

The FormInputComponent template:

<div>
  <label attr.for="{{name}}">{{label}}</label>
  <input [(ngModel)]="model" type="{{type}}" placeholder="{{placeholder}}" alt="{{alt}}" id="{{name}}">
</div>
<pre>{{model}}</pre>

Now the problem is that I can only see the changes from the pre element that lies inside the FormInputComponent template, but the parent, CoreComponent's pre element remains unchanged.

I looked at this question which is in the ballpark of what I want to achieve but not quite since using a service for just returning a value up the hierarchy seems like overkill and a bit messy if you have multiple FormInputComponents on the same page.

So my question is simple, how can I pass a model to FormInputComponent and letting it return a new value whenever the value changes so that the public user in CoreComponent changes automatically?

解决方案

To be able to use two way binding short when using your component you need to readme your output property to modelChange:

export class FormInputComponent implements DoCheck {
  @Input() model: string;
  @Output() modelChange: EventEmitter = new EventEmitter();

  ngDoCheck() {
    this.modelChange.next(this.model);
  }
}

And use it this way:

<form-input [(model)]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [(model)]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>

这篇关于如何在角度2的组件之间使用双向数据绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆