我使用 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
请帮助。
答案 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);
}
这将创建一个绑定到父上下文的函数。
但是,正如我已经指出的,我建议遵循第一种方法。
希望能帮助您理解该问题。