用于 2 种 属性 绑定的 Angular2 装饰器

Angular2 decorator for 2 way property binding

来自 Victor Savkin 在 Angular2 template syntax 上的 post,展示了如何使用输入和输出 属性 绑定 -

<todo-cmp [model]="todo" (complete)="onCompletingTodo(todo)"></todo-cmp>

@Component({selector: 'todo-cmp'})
class TodoCmp {
  @Input() model;
  @Output() complete = new EventEmitter(); // TypeScript supports initializing fields
}

输入 属性 用 @Input() 装饰,而输出 属性 用 @Output() 修饰。 我应该如何声明一个 属性 将有一个 2 路 属性 绑定? 示例:假设 rootpanel 组件有 'suggestions' 属性(字符串类型)并且 searchPanel 有 'getSuggestions 属性。现在我希望这两个属性以两种方式相互绑定。 我试过了 -

rootpanel.html:

<search-panel [(getSuggestions)]="suggestions"> </search-panel>

但是我在 searchPanel 组件中声明 getSuggestions 属性 时卡住了。 另外,getSuggestions 的类型应该是什么 属性 - string or EventEmitter<string>?

求推荐。

如果你想要two-way来自父组件的模型绑定:

[(model)]

您的子组件中需要以下内容:

@Input() model: string;
@Output() modelChange:EventEmitter<string>;

当模型在您的子组件中被覆盖时,您将发出 modelChange 事件:

updateModel(newValue:string) {
    this.model = newValue;
    this.modelChange.emit(this.model);
}

从父组件的角度来看,[(model)]相当于:

[model]="model"  (modelChange)="model=$event"

这样,当模型属性在子组件内部发生变化时,模型的变化会通过two-way绑定向上传播,沿途同步所有绑定的模型。

如果您想对 two-way-binding 使用 [(getSuggestions)] 样式,请将字段声明为

class TodoCmp {
  @Input() getSuggestions;
  @Output() getSuggestionsChange = new EventEmitter(); 

  onClick() {
    getSuggestions = 'someValue';
    getSuggestionsChange.emit(getSuggestions);
  }
}

getSuggestions 对于这样的 input/output 组合可能不是一个好的选择,但它应该展示它们是如何连接的。输出需要与输入同名并附加 Change。 如果此命名方案不适合使用您的组件,例如

<search-panel [suggestions]="suggestions" (getSuggestions)="updateSuggestions($event)> </search-panel>

和input/output喜欢

class TodoCmp {
  @Input() suggestions;
  @Output() getSuggestions = new EventEmitter(); 

  onClick() {
    suggestions = 'someValue';
    getSuggestions.emit(getSuggestions);
  }
}

pixelbits 推荐的方法正是您应该如何做到这一点,但是如果您在一个组件上有多个双向数据绑定属性,或者甚至在您的代码库中经常更改的属性,我为此创建了一个装饰器。 如果您使用的是 npm here 。 如果您需要代码,请转到 gihub 页面。

有了这个,你可以直接使用:

import { Component } from '@angular/core';
import { TwoWay } from 'two-way-decorator';
 
@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss']
})
export class ExampleComponent {
 
  @TwoWay()
  public text: string;
 
  @TwoWay()
  public count: number;
 
}