【问题标题】:Angular2 组件@Input 双向绑定
【发布时间】:2017-06-19 19:02:15
【问题描述】:

我有一个数据驱动的 Angular 应用程序。我有一个切换组件,我以切换状态传递。我的问题是,除非我将切换布尔值作为对象传递,否则双向数据绑定似乎不起作用。有没有办法让这个工作不使用 EventEmitter 或将变量作为对象传递。这是一个可重用的组件,并且应用程序是大量数据驱动的,因此将值作为对象而不是选项传递。我的代码是......

toggle.html

<input type="checkbox" [(ngModel)]="toggled" [id]="toggleId" name="check"/>

toggle.component.ts

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

@Component({
  moduleId: module.id,
  selector: 'toggle-switch',
  templateUrl: 'toggle-switch.component.html',
  styleUrls: ['toggle-switch.component.css']
})

export class ToggleSwitchComponent {

  @Input() toggleId: string;
  @Input() toggled: boolean;

}

parent.component.html

<toggle-switch toggleId="toggle-1" [(toggled)]="nongenericObject.toggled"></toggle-switch>

【问题讨论】:

  • 我想强调米奇对此评论的重要性。要使用父组件的 var 进行双向绑定,必须将 @Output 装饰的 EventEmitter 命名为相应的 @Input,并在末尾加上 Change 后缀,如:@Input( ) 切换:布尔值; @Output() toggledChange: EventEmitter = new EventEmitter();

标签: angular typescript data-binding components decorator


【解决方案1】:

为了让[(toggled)]="..." 工作,你需要

  @Input() toggled: boolean;
  @Output() toggledChange: EventEmitter<boolean> = new EventEmitter<boolean>();

  changeValue() {
    this.toggled = !(this.toggled); 
    this.toggledChange.emit(this.toggled);
  }

另见Two-way binding

[更新] - 2019 年 6 月 25 日
来自@Mitch 下面的评论:
值得注意的是@Output名称必须与@Input名称相同,但以Change结尾。你不能称它为onToggle 之类的。这是一个语法约定。

【讨论】:

  • 他会非常失望,因为不能满足“不使用 EventEmitter 或将变量作为对象传入”。好像他没看过基础语法,哦,嘿,语法指南的链接。
  • 他甚至导入了EventEmitter。它可能没有你想象的那么糟糕;-)
  • @silentsod Angular 没有内置的方法来处理一个属性上的 2 路绑定,这还是很烦人的。似乎是一个超级基本的功能;但是,它根本不受支持。此外,Angular 文档非常复杂且难以理解,因此如果 OP 即使在阅读后仍不了解如何执行此操作,我也不会感到惊讶。
  • 值得注意的是@Output名称必须与@Input名称相同,但以Change结尾。你不能称它为onToggle 之类的。这是一个语法约定。
  • @ProxyTech 记录在这里:angular.io/guide/two-way-binding:The [()] syntax is easy to demonstrate when the element has a settable property called x and a corresponding event named xChange。但是我同意应该强调这一点。
【解决方案2】:

虽然问题已经超过 2 年了,但我想贡献我的 5 美分...

这不是 Angular 的问题,而是关于 Javascript 的工作原理...简单变量(数字、字符串、布尔值等)通过值传递,而复杂变量(对象、数组)通过引用传递:

您可以在 Kyle Simpson 的系列你不懂 js 中阅读更多相关信息:

https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch2.md#value-vs-reference

因此,您可以使用 @Input() 对象变量在组件之间共享作用域,而无需使用发射器、观察器和任何类似的东西。

// In toggle component you define your Input as an config object
@Input() vm: Object = {};

// In the Component that uses toggle componet you pass an object where you define all needed needed variables as properties from that object:
config: Object = {
    model: 'whateverValue',
    id: 'whateverId'
};

<input type="checkbox" [vm]="config" name="check"/>

通过这种方式,您可以修改所有对象属性并在两个组件中获得相同的值,因为它们共享相同的引用。

【讨论】:

  • 这既是祝福,也是噩梦。我曾经有过一段非常糟糕的时光,因为引用正在被传递而我不知道并且创建了一个错误票。我不明白为什么会这样,甚至创建新对象等等。但是现在,我只需要一个简单的双向绑定,它就可以完美地工作
  • 链接已损坏 - 看起来他们正在完成新版本,但原版仍然存在:github.com/getify/You-Dont-Know-JS/blob/1st-ed/…
猜你喜欢
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
  • 1970-01-01
  • 2017-11-07
  • 2016-08-20
  • 1970-01-01
相关资源
最近更新 更多