【问题标题】:How to bind on emitted value from eventemitter from the template如何绑定来自模板的事件发射器发出的值
【发布时间】:2021-06-30 03:07:02
【问题描述】:

我正在学习如何使用 @Input、@Output 和 EventEmitter 装饰器在父子之间进行绑定。 在下面的代码中

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

我创建了一个事件发射器,它会在对字符串参数调用方法 addNewItem 时发出一个值。 在我调用的 addNewItem 方法的主体中

this.newItemValue.emit(val);

我想在 this.newItemValue 上绑定,所以我在 html 文件中做了以下操作

<button appItemDetails (click) = addNewItem(newItem.value)>add new item</button>
<p (newItemValue)="onlyNewlyAddedItems($event)"></p>

但是当我编译应用程序时,我收到了下面发布的错误。 请让我知道如何从模板中绑定 this.newItemValue

错误

Failed to compile.

src/app/app.component.html:4:40 - error TS2345: Argument of type 'Event' is not assignable to parameter of type 'string'.

4 <p (newItemValue)="onlyNewlyAddedItems($event)"></p>
                                         ~~~~~~

  src/app/app.component.ts:5:16
    5   templateUrl: './app.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component AppComponent.
    

app.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'InputOutputBindings';
  currentItem = 'TV';
  items = ['item1', 'item2', 'item3', 'item4'];

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

  addNewItem(val : string) {
    this.newItemValue.emit(val);
    console.log("add new item:" + val);
    this.items.push(val);
    console.log("add new item:" + this.items);
  }

  onlyNewlyAddedItems(val : string) {
    console.log("onlyNewlyAddedItems:" + val);
  }
}

item-details.directive.ts

import { Directive, Input, Output, EventEmitter } from '@angular/core';
@Directive({
  selector: '[appItemDetails]',
  exportAs: 'customdirective'
})
export class ItemDetailsDirective {

  @Input() item : string = "";

  constructor() { }

  ngOnInit() {
    console.log("ngOnInit->:" + this.item)
  }

  ngOnChange() {}
}

app.coponent.html

<h1 #test = customdirective appItemDetails [item]="currentItem">{{currentItem}}  item</h1>
<label>Add an item: <input #newItem></label>
<button appItemDetails (click) = addNewItem(newItem.value)>add new item</button>
<p (newItemValue)="onlyNewlyAddedItems($event)"></p>

【问题讨论】:

  • 您的&lt;p&gt; 标签不会引发名为newItemValue 的事件。您很可能希望在按钮单击中将值设置为变量并使用插值显示该变量(例如{{newItemValue}})。在 Angular 中,使用 [prop]{{prop}} 语法表示“绑定到显示值或输入”,(eventName) 表示“绑定到事件或输出”。
  • @pascalpuetz 请您看一下上面的 app.component.ts...它已经回答了您的询问
  • @LetsamrIt,看看我的回答。
  • @LetsamrIt 我没有任何询问吗?首先引起我注意的问题是,您尝试将一个事件(newItemValue) 绑定到一个普通的html 标记&lt;p&gt;,它永远不会调度一个名为(newItemValue) 的事件。做&lt;p (newItemValue)="myFunc()"&gt; 大致相当于document.getElementById('myPElement').addEventListener('newItemValue', () =&gt; this.myFunc())。请注意“大致”,它并不完全相同,但概念是。

标签: angular typescript angular-directive


【解决方案1】:

我观察到了你的问题。

我认为你误解了这个概念。

在您的示例中,您毫无必要地使用了EventEmitter。因为如果您没有任何父/子情况,您可以通过简单的按钮单击来处理添加新项目。

所以,我重构了你的例子。

我添加了一个 test 组件,其中我添加了您的文本框。

test.component.html

<h1 #test=customdirective appItemDetails [item]="currentItem">{{currentItem}} item</h1>
<label>Add an item: <input #newItem></label>
<button appItemDetails (click) = addNewItem(newItem.value)>add new item</button>

test.component.ts

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

@Component({
  selector: 'test',
  templateUrl: './test.component.html'
})
export class TestComponent {
  @Output() newItemAdded = new EventEmitter<string>();

  title = 'InputOutputBindings';
  currentItem = 'TV';

  addNewItem(value: string) {
    this.newItemAdded.emit(value);
  }
}import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'test',
  templateUrl: './test.component.html'
})
export class TestComponent {
  @Output() newItemAdded = new EventEmitter<string>();

  title = 'InputOutputBindings';
  currentItem = 'TV';

  addNewItem(value: string) {
    this.newItemAdded.emit(value);
  }
}

然后我将test 组件作为子组件包含在app 组件下。

app.component.html

<test (newItemAdded)="newItemAdded($event)"></test>
<h3>TV items: </h3>
<div>
  <ul *ngFor="let item of items">
    <li>{{item}}</li>
  </ul>
</div>

app.component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  items = ['item1', 'item2', 'item3', 'item4'];

  newItemAdded(val : string) {
    console.log("onlyNewlyAddedItems:" + val);
    this.items.push(val);
  }
}

我已向您的父 (app) 组件添加了一个项目列表。所以,现在我们可以使用EventEmitter,因为我们想将新添加的item显示到父(app)组件的列表中。

test 组件上,当单击add new item 按钮时会发出事件,该事件由app 组件捕获。然后我们将新项目添加到现有的items 数组中。

仔细观看演示。

StackBlitz 的工作演示。

【讨论】:

  • 您能告诉我如何让我的示例正常工作吗?我需要更改或添加什么?!尝试学习您的示例时我感到有点失落……谢谢
  • 不明白的地方请写分。
猜你喜欢
  • 1970-01-01
  • 2021-08-11
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 2018-06-03
相关资源
最近更新 更多