仅在某些元素上调用的 Angular2 事件
Angular2 event called only on SOME of the elements
所以我有一个带有表单的模态组件,该组件用于创建数据库条目和编辑现有条目。
它有一个 onSubmit
事件的订阅选项,该事件在成功提交后执行。
由于某种原因发生的是该组件的一些元素订阅执行而另一些不会执行,看起来 "create-mode" 上的那些将执行而 "edit-mode" 上的那些不会执行。
代码部分
CreateOrUpdateTransactionComponent:
@Component({
selector: 'create-update-transaction',
templateUrl: './CreateOrUpdateTransaction.html',
providers: [AccountTransactionsService]
})
export class CreateOrUpdateTransactionComponent {
closeResult: string;
modalRef: NgbModalRef;
@Input() transaction: Transaction = new Transaction();
@Input() isCreate: boolean;
@Output() onSubmit: EventEmitter<void> = new EventEmitter<void>();
constructor(private modalService: NgbModal,
private transactionsService: AccountTransactionsService) {}
sendTransaction(): void{
let localModalRef = this.modalRef;
this.transactionsService.createOrUpdateTransaction(this.transaction, (isSuccessful)=>{
if (isSuccessful) {
this.onSubmit.emit(); //<--- The problem is here
localModalRef.close();
}
});
}
}
HTML:
<table>
<caption>Account Transactions</caption>
<thead>
// Omitted thead
</thead>
<template let-transaction ngFor [ngForOf]="accountTransactions" let-i="index">
<tr data-toggle="collapse" [attr.data-target]="'#'+i">
// Omitted <td>s
<td> //<----These updateTransactions() are not being executed
<create-update-transaction [isCreate]="false" [transaction]="transaction" (onSubmit)="updateTransactions()"></create-update-transaction>
</td>
</tr>
<div class="container collapse" [attr.id]="i">
// some content
</div>
</template>
</table>
<create-update-transaction [isCreate]="true" (onSubmit)="updateTransactions()"></create-update-transaction>
//<---- This updateTransactions() successfully executes
通知
- 如果我只在 table 中显示一行而不使用
ngFor
(保持对后端的调用以更新数据库),它工作得很好。
知道为什么会这样吗?
提前致谢!
更新1
调试我注意到,在创建模式下,this.onSubmit.observers
是一个包含一个观察者的数组,而在编辑模式下,它是一个包含 0 个观察者的数组,所以这就是问题所在。知道为什么吗?
更新2
再次调试,发现this.transactionsService.createOrUpdateTransaction...
中的this
没有问题,其onSubmit.observers
包含1个观察者,在到达回调代码之前,其中this.onSubmit.observers
是一个包含 0 个观察者的数组
账户交易服务:
@Injectable()
export class AccountTransactionsService{
private loggedBankAccount: number;
private queryObservable: ObservableQuery;
constructor(private userManagingService: UserManagingService) {
this.loggedBankAccount = userManagingService.getLoggedBankAccountNumber();
this.queryAccountTransactions();
}
queryAccountTransactions(): void{
this.queryObservable = // querying the back-end
}
createOrUpdateTransaction(transaction: Transaction, callback: (isSuccessfull: boolean) => void): void{
let isSuccessful: boolean = false;
client.mutate(/*inserting the backend*/).then((graphQLResult) => {
const { errors, data } = graphQLResult;
if (data) {
console.log('got data', data);
isSuccessful = true;
}
if (errors) {
console.log('got some GraphQL execution errors', errors);
}
callback(isSuccessful);
}).catch((error) => {
console.log('there was an error sending the query', error);
callback(isSuccessful);
});
}
getAccountTransactions(): ObservableQuery{
return this.queryObservable;
}
}
通知
- 如果我只执行给
AccountTransactionService.createOrUpdateTransaction
的回调(删除对后端的调用以实际更新数据库),它工作得很好,所有订阅者都对此 onSubmit
事件正在呼叫中。
this
控制台图像
设置null
作为参数:
this.onSubmit.emit(null);
所以我发现情况是 ngFor
绑定到的数据在我更新后端时被新实例替换,因此,它重新呈现它的子组件导致重新初始化(destory + init ),这使得 Component 的实例被覆盖。
为了解决这个问题,我已经将 accountTransaction
的查询更改为仅在父组件初始化时查询一次,并且再也不会 refetch
ing (这会触发重新渲染)。
只有在服务器端成功时,我才会向客户端显示更改,如果失败,我会使用数据备份,这样客户端就可以在没有 [=12] 的情况下保持服务器的真实状态更新=]ing
对于未来的观察者:
问题的关键是父组件的 *ngFor
依赖于子组件中正在更改的数据,导致重新初始化 *ngFor
(子组件) BEFORE 完成子组件方法的执行。
希望对大家有所帮助:)
所以我有一个带有表单的模态组件,该组件用于创建数据库条目和编辑现有条目。
它有一个 onSubmit
事件的订阅选项,该事件在成功提交后执行。
由于某种原因发生的是该组件的一些元素订阅执行而另一些不会执行,看起来 "create-mode" 上的那些将执行而 "edit-mode" 上的那些不会执行。
代码部分
CreateOrUpdateTransactionComponent:
@Component({
selector: 'create-update-transaction',
templateUrl: './CreateOrUpdateTransaction.html',
providers: [AccountTransactionsService]
})
export class CreateOrUpdateTransactionComponent {
closeResult: string;
modalRef: NgbModalRef;
@Input() transaction: Transaction = new Transaction();
@Input() isCreate: boolean;
@Output() onSubmit: EventEmitter<void> = new EventEmitter<void>();
constructor(private modalService: NgbModal,
private transactionsService: AccountTransactionsService) {}
sendTransaction(): void{
let localModalRef = this.modalRef;
this.transactionsService.createOrUpdateTransaction(this.transaction, (isSuccessful)=>{
if (isSuccessful) {
this.onSubmit.emit(); //<--- The problem is here
localModalRef.close();
}
});
}
}
HTML:
<table>
<caption>Account Transactions</caption>
<thead>
// Omitted thead
</thead>
<template let-transaction ngFor [ngForOf]="accountTransactions" let-i="index">
<tr data-toggle="collapse" [attr.data-target]="'#'+i">
// Omitted <td>s
<td> //<----These updateTransactions() are not being executed
<create-update-transaction [isCreate]="false" [transaction]="transaction" (onSubmit)="updateTransactions()"></create-update-transaction>
</td>
</tr>
<div class="container collapse" [attr.id]="i">
// some content
</div>
</template>
</table>
<create-update-transaction [isCreate]="true" (onSubmit)="updateTransactions()"></create-update-transaction>
//<---- This updateTransactions() successfully executes
通知
- 如果我只在 table 中显示一行而不使用
ngFor
(保持对后端的调用以更新数据库),它工作得很好。
知道为什么会这样吗?
提前致谢!
更新1
调试我注意到,在创建模式下,this.onSubmit.observers
是一个包含一个观察者的数组,而在编辑模式下,它是一个包含 0 个观察者的数组,所以这就是问题所在。知道为什么吗?
更新2
再次调试,发现this.transactionsService.createOrUpdateTransaction...
中的this
没有问题,其onSubmit.observers
包含1个观察者,在到达回调代码之前,其中this.onSubmit.observers
是一个包含 0 个观察者的数组
账户交易服务:
@Injectable()
export class AccountTransactionsService{
private loggedBankAccount: number;
private queryObservable: ObservableQuery;
constructor(private userManagingService: UserManagingService) {
this.loggedBankAccount = userManagingService.getLoggedBankAccountNumber();
this.queryAccountTransactions();
}
queryAccountTransactions(): void{
this.queryObservable = // querying the back-end
}
createOrUpdateTransaction(transaction: Transaction, callback: (isSuccessfull: boolean) => void): void{
let isSuccessful: boolean = false;
client.mutate(/*inserting the backend*/).then((graphQLResult) => {
const { errors, data } = graphQLResult;
if (data) {
console.log('got data', data);
isSuccessful = true;
}
if (errors) {
console.log('got some GraphQL execution errors', errors);
}
callback(isSuccessful);
}).catch((error) => {
console.log('there was an error sending the query', error);
callback(isSuccessful);
});
}
getAccountTransactions(): ObservableQuery{
return this.queryObservable;
}
}
通知
- 如果我只执行给
AccountTransactionService.createOrUpdateTransaction
的回调(删除对后端的调用以实际更新数据库),它工作得很好,所有订阅者都对此onSubmit
事件正在呼叫中。
this
控制台图像
设置null
作为参数:
this.onSubmit.emit(null);
所以我发现情况是 ngFor
绑定到的数据在我更新后端时被新实例替换,因此,它重新呈现它的子组件导致重新初始化(destory + init ),这使得 Component 的实例被覆盖。
为了解决这个问题,我已经将 accountTransaction
的查询更改为仅在父组件初始化时查询一次,并且再也不会 refetch
ing (这会触发重新渲染)。
只有在服务器端成功时,我才会向客户端显示更改,如果失败,我会使用数据备份,这样客户端就可以在没有 [=12] 的情况下保持服务器的真实状态更新=]ing
对于未来的观察者:
问题的关键是父组件的 *ngFor
依赖于子组件中正在更改的数据,导致重新初始化 *ngFor
(子组件) BEFORE 完成子组件方法的执行。
希望对大家有所帮助:)