角点击回调未定义服务

时间:2019-10-02 19:31:46

标签: javascript angular angular6

我使用 Anuglar 6 编写的应用程序存在问题。 我创建了一个简单的商品组件

@Component({
  selector: 'product-grid-item',
  styleUrls: ['./product.grid.item.component.scss'],
  templateUrl: './product.grid.item.component.html',
})
export class ProductGridItemComponent {
  @Input()
  item: Product;

  @Input()
  onClick: Function;
}

在html中,我有点击监听器

<span [attr.data-product-id]="item.id" class="fa fa-edit" (click)="onClick($event)"></span>

在父组件中,我传递了回调函数

    class="col-md-6 col-xl-4" [onClick]="onProductEditClick" [item]="productItem">

我的监听器定义如下

  constructor(private store: Store, private dialogService: NbDialogService) {
  }

  onProductEditClick(elem) {
    const productId = elem.target.getAttribute("data-product-id");
    const dialogRef = this.dialogService.open(EditProductDialog, {context: {productId: productId}});
  }

但是当我尝试单击“编辑”按钮时,出现以下错误

zone.js:192 Uncaught TypeError: Cannot read property 'open' of undefined

请帮助。

1 个答案:

答案 0 :(得分:1)

主要问题是,当函数作为回调传递时在上下文中执行 您的子组件。在这种情况下,Javascript中神奇的this关键字将指向子组件。

此外,使用@Input传递回调不是一个好习惯。

您可以通过两种方式解决该问题:

首先,我建议使用常规做法并利用@Output来通知有关子组件的事件。 要在您的代码中应用此方法,您可以按以下方式对其进行重构:

@Component({
  selector: 'product-grid-item',
  styleUrls: ['./product.grid.item.component.scss'],
  templateUrl: './product.grid.item.component.html',
})
export class ProductGridItemComponent {
  @Input()
  item: Product;

  @Output()
  onItemClick: EventEmitter<Product> = new EventEmitter<Product>();

  constructor() {
  }

  onProductEditClick() {
    this.onItemClick.emit(this.item);
  }
}

在您的父组件中:

class="col-md-6 col-xl-4" (onItemEditClick)="onProductEditClick($event)" [item]="productItem">

第二种方法是创建绑定函数并将其作为回调传递:

public boundedClickListener: Function;

public ngOnInit(){
    this.boundedClickListener = this.onProductEditClick.bind(this);
}

这将创建一个绑定到父上下文的函数。

但是,正如我已经指出的,我建议遵循第一种方法。

希望能帮助您理解该问题。