57

我制作了一个简单的 UI,它包含两个组件(父组件和子组件)。

UI 所做的是,当我在 Child 组件的输入框中键入一些内容时。该值将使用 ngModel 更改。

子组件以这种方式工作得很好。

// Child Component
@Component({
    selector: 'child',
    template: `
        <p>{{sharedVar}}</p>
        <input [(ngModel)]="sharedVar">
    `
})
export class ChildComponent {
    sharedVar: string;
}

现在我有一个父组件,我打算使用与子组件相同的值。

我将子组件添加到父模板中,并使用依赖注入来调用子组件的sharedVar.

// Parent Component
@Component({
    selector: 'parent',
    template: `
        <h1>{{sharedVar}}</h1>
        <child></child>
    `,
    directives: [ChildComponent],
    providers: [ChildCompnent]
})
export class ParentComponent {
    sharedVar: string;
    constructor(child: ChildComponent) {
        this.sharedVar = child.sharedVar;
    }
}

问题是当我在输入框中输入时,值<p>会自动更改,而父组件中的值<h1>不会更改。

4

3 回答 3

117

我们可以使用[(x)]父模板中的语法来实现与子模板的双向数据绑定。如果我们用 name 创建一个 Output 属性xChange,Angular 会自动更新 parent 属性。emit()但是,每当孩子更改值时,我们确实需要一个事件:

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

@Component({
    selector: 'child',
    template: `
        <p>Child sharedVar: {{sharedVar}}</p>
        <input [ngModel]="sharedVar" (ngModelChange)="change($event)">
    `
})
export class ChildComponent {
    @Input() sharedVar: string;
    @Output() sharedVarChange = new EventEmitter();
    change(newValue) {
      console.log('newvalue', newValue)
      this.sharedVar = newValue;
      this.sharedVarChange.emit(newValue);
    }
}

@Component({
    selector: 'parent',
    template: `
        <div>Parent sharedVarParent: {{sharedVarParent}}</div>
        <child [(sharedVar)]="sharedVarParent"></child>
    `,
    directives: [ChildComponent]
})
export class ParentComponent {
    sharedVarParent ='hello';
    constructor() { console.clear(); }
}

Plunker

sharedVarParent在 ParentComponent 中使用只是为了证明父子组件中的名称不必相同。

于 2016-02-11T02:03:02.637 回答
4

您可以设置outputs从子到父的事件发射器通信 ( )。例如像这样:

@Component({
    selector: 'child',
    template: `
        <p>Child: {{sharedVar}}</p>
        <input [(ngModel)]="sharedVar" (ngModelChange)="change()">
    `
})
export class ChildComponent {
    @Output() onChange = new EventEmitter();
    sharedVar: string;
    change() {
        this.onChange.emit({value: this.sharedVar});
    }
}

和父组件:

@Component({
    selector: 'parent',
    template: `
        <h1>{{sharedVar}}</h1>
        <child (onChange)="sharedVar = $event.value"></child>
    `,
    directives: [ChildComponent]
})
export class ParentComponent {
    sharedVar: string;
    constructor() {

    }
}

演示: http ://plnkr.co/edit/T2KH4nGKPSy6GEvbF1Nb?p=info

于 2016-02-10T23:54:10.043 回答
2

如果你想在同一个组件中有多个双向数据绑定,你可以这样做

export class ComponentName {
    @Input() public first: string = '';
    @Input() public second: string = '';
    @Output() public firstChange = new EventEmitter();
    @Output() public secondChange = new EventEmitter();

    public functionName1(first: string): void {
        this.first = first;
        this.firstChange.emit(first);
    }

    public functionName2(second: string): void {
        this.second = second;
        this.secondChange.emit(second);
    }
}

当输入和输出被命名为“x”和“xChange”时,它会在属于一起的父级中自动检测它们。

我认为这实际上是比已接受答案中的更好的做法,因为在这里它立即清楚地说明了名称之间的关系。

于 2021-01-27T12:38:43.450 回答