【问题标题】:Two way data binding in angular not working角度中的两种方式数据绑定不起作用
【发布时间】:2018-10-03 16:51:05
【问题描述】:

我正在尝试在角度组件中实现两种方式的数据绑定。目前它处于父子模式。

parent.component.html

<child [(title)]="title"></child>
<span style="color: red">This is parent component {{title}}</span>

parent.component.ts

title = 'app';

child.component.html

<span style="color: blue">This is child component {{title}}</span>

child.component.ts

@Input() title: any;
  @Output() pushTitle = new EventEmitter();

  constructor() { }

  ngOnInit() {
    this.title = 'new title';
    this.pushTitle.emit(this.title);
  }

当我从子组件更改标题时,标题也应该在父组件上实现。另外,我不确定为什么父代码会无缘无故地循环。我在 html 中添加了文本只是为了测试它是否在两个组件中都更新了,但它只在子组件中更新,而不是在父组件中更新。我来自 angularjs 背景,两种方式的数据绑定在其中无缝工作。我只是对自己做错了什么感到困惑(我知道这是一个菜鸟问题)。

在这里演示:https://stackblitz.com/edit/angular-xttmxg

【问题讨论】:

  • 简单的方法是从@Output() pushTitle = new EventEmitter();更新到@Output() titleChange = new EventEmitter();

标签: javascript angular


【解决方案1】:

双向数据绑定仅适用于模板-组件交互。

如果您想将标题更改发送到父组件,您应该执行以下操作:

父模板和组件:

<child [title]="title" (pushTitle)="onTitleChange(value)"></child>
<span style="color: red">This is parent component {{title}}</span>

onTitleChange(value) {
    this.title = value;
}

后续问题:

模板:

 <input [(ngModel)]="inputModel">

组件:

inputModel: string;

现在,每次您在输入字段中输入内容时,您都会看到组件模型的变化,或者当以编程方式更改 inputModel 值时,您将看到 HTML 输入的变化。

【讨论】:

  • 谢谢。那么在什么情况下我可以使用 [(title)] 呢?
  • 编辑了答案。
  • 如果@ritaj 的回答让您满意,您应该将他的回答标记为正确。谢谢。
【解决方案2】:

还有另一种方法可以达到同样的效果。

@Input() title: any;
@Output() titleChange: EventEmitter<any> = new EventEmitter<any>();

changeValue() {
  this.title= !title;
  this.titleChange.emit(this.title);
}

看看 Angular documentation 关于双向绑定

【讨论】:

  • 这毫无意义。你会得到一个错误title is not defined
  • 让我创建一个 stackblitz :)
  • 请重新阅读您给出的答案。它使用未定义的变量。除此之外,是的,这绝对有效。干得好!
  • @RukshanDangalla,stackblitz 代码太棒了!我只有一个问题,我不能只使用 [(fontSizePx)]="fontSizePx",并将输入变量分配为 fontSizePx 吗?而不是使用大小?
【解决方案3】:

您以某种方式使用 2-way-binding 创建了一个无限更新周期。这会导致您注意到的无限循环和最终的堆栈溢出。


要解决此问题,您最好为titleChange 事件添加一些逻辑(这是 banana-in-a-box 的 banana-部分 语法,即[(title)] 中括号中的部分,它会自动转换为名为@9​​87654324@ 的事件发射器)。 例如,如果父组件的title 属性等于子组件发出的更新,您可能希望跳过更新它。

这意味着您应该将[(title)] 拆分为(titleChange)="titleChange($event)"[title]="title"。第一部分让您将更新后的标题作为$event 传递,然后在函数titleChanged 中处理它(在这种情况下,名称是任意的)。第二部分的作用是子组件接收父组件的title属性的更新。

另一种常见的模式是将title设为私有(通常带有前缀下划线,例如_title),然后添加一个getter get title() { return this._title;},这样您就可以(1)封装这个属性并(2)添加一些处理. 在你的情况下,这不是必需的,但它也不会受到伤害。 ;-)


这是一个包含这些更改的plunkr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    相关资源
    最近更新 更多