【问题标题】:Unsure how to apply two-way binding on Angular for a custom component不确定如何在 Angular 上为自定义组件应用双向绑定
【发布时间】:2019-08-18 18:32:17
【问题描述】:

我有一个视图组件,它从服务中获取数据模型并将其设置为自身的属性。 然后,一组自定义组件接收属性的字段作为输入以在其中显示。这按预期工作。

<app-textbox [caption]="'First name'"
             [value]="data.name.first"></app-textbox>

ngOnInit() {
  this.service.getData()
    .subscribe(res => this.data = res);
}

当自定义组件编辑其内容时,我注意到原始模型没有更新。经过一番谷歌搜索后,我发现我需要双向绑定它并尝试了以下方法(显然它被称为香蕉盒符号)。遗憾的是,它似乎没有任何效果,并且原始模型没有随着新条目而改变。

<app-textbox [caption]="'First name'"
             [(value)]="data.name.first"></app-textbox>

我还尝试应用 ngModel,如下所示,但这导致错误消息提示 没有用于具有未指定名称属性的表单控件的值访问器。检查docs 让我知道它应该可以工作,但没有我需要的那么详细。

<app-textbox [caption]="'First name'"
             [(ngModel)]="data.name.first"></app-textbox>

我需要一个指向哪里出错的指针。我需要在自定义组件中的某个地方发出值吗?我必须使用表格吗?我现在唯一解决它的想法是标记所有控件并手动收集值。这显然是一种不好的做法。

【问题讨论】:

    标签: angular typescript angular-ngmodel two-way-binding


    【解决方案1】:

    是的,您是对的,您需要从子组件发出事件,并且您需要在事件名称中添加后缀“更改”。在你的情况下应该是

    @Output() valueChange = new EventEmitter<string>();
    
    

    只有这样 Angular 才能识别 [()] 语法。

    【讨论】:

    • 你是说如果我有@Input() beep 并从@Output() beepChange 发出,那么Angular 会自动为我解决吗?听起来很棒,但我还没有看到这方面的任何信息。它记录在哪里?除了 Change 之外,我可以使用其他后缀吗?
    • 是的,它可以完美运行,您只需要使用“[()]”语法,不,您不能更改后缀。
    • codesandbox.io/embed/angular-m69cp 看看我为你创建的这个例子。应用组件中的值将在 5 秒后自动更改。
    • 好吧,我会被诅咒的。它似乎工作!您是否有任何记录该行为的参考资料?似乎没有必要实现 ControlValueAccessor 但这是最​​广泛传播的建议。你是怎么知道的?
    • 我很久以前读过一篇关于它的文章,但现在找不到了:p
    【解决方案2】:

    您的组件必须是表单控件并实现 ControlValueAccessor。您可以在此处阅读更多信息,例如 https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html。如果你的组件做了一些“输入式”的东西(输入和显示文本),就会出现这种情况。

    或者你应该在你的组件中添加一个@Input() 和一个@Output() 并以你需要的方式处理它。在这种情况下,您的绑定将被拆分,并且模板看起来像 &lt;app-textbox [caption]="'First name'" (change)="handleChange($event)"&gt;&lt;/app-textbox&gt;。在此示例中,@Input()caption@Output()change

    【讨论】:

    • 啊哈!所以是吠叫正确的二叉树,呵呵。我的组件是 input'ish,你在那里完全正确。如果我选择第二种方法并发出更改,那将是 Angular 认可的约定(只要它被精确地称为 change)还是我仍然需要手动将发出的更改映射到视图组件? (我正在考虑 Krishna 建议的解决方案。尚未对其进行测试,但它似乎好得令人难以置信,我怀疑还有更多。)你怎么看?
    • @DonkeyBanana 你可以随意命名。 changevalueChange 都有意义。我认为后缀 change 不会自动创建您正在谈论的连接。据我所知,它只适用于ngModel,所以[(ngModel)] 可以拆分为[ngModel](ngModelChange)。在我的示例中,您必须将 @Output() change = new EventEmitter&lt;string&gt;() 添加到组件的模板中。然后在需要时发出更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2017-09-21
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 2020-02-27
    相关资源
    最近更新 更多