Angular5:需要阻止 ngbTooltip 在从可观察的数据返回之前呈现
Angular5: Need to prevent ngbTooltip from rendering before data is returned from observable
我是 angular 2+ 的新手,继承了一个不完整的项目。我的目标是创建一个工具提示,用于检查特定字段的审计详细信息并显示它们。一个例子可能是:
"Updated by Seth, on 8/18/18."
为此,我创建了一个组件 angular,它通过服务传回所有相关信息。通过查看 Web 调试器,我可以看到服务调用按预期工作。不幸的是,正在呈现的是带有以下不完整文本的工具提示:
"updated by , "
这是我的组件模板。
<ng-template #tipContent>
<span *ngIf="loadCompleted">Updated By {{ auditDetail.updatedBy }}, {{ auditDetail.updatedAt | amTimeAgo }}</span>
</ng-template>
<i [ngbTooltip]="tipContent" (mouseenter)="refreshAuditDetail()" class="fas fa-info-circle fa-sm"></i>
这是组件打字稿。
@Component({
selector: 'audit-tooltip',
templateUrl: './audit-tooltip.component.html',
styleUrls: ['./audit-tooltip.component.css']
})
export class AuditTooltipComponent {
@Input() plan: Plan;
@Input() fieldName: string;
auditDetail: AuditDetail;
loadCompleted: boolean = false;
constructor(private planService: PlanService) { }
refreshAuditDetail() {
var planId = this.plan.id;
var fieldName = this.fieldName;
var fieldValue = this.plan[this.fieldName];
this.loadCompleted = false;
this.planService.getAuditDetails(planId, fieldName, fieldValue)
.subscribe((auditDetail: AuditDetail) => {
console.log(auditDetail);
this.auditDetail = auditDetail;
}, () => {}, () => this.loadCompleted = true);
}
}
而且,如有必要,这里是我使用它的地方。
<h5 class="card-title">{{fieldLabel}}<audit-tooltip [fieldName]="fieldName" [plan]="plan"></audit-tooltip> </h5>
我错过了什么?
考虑使用 OnInit 生命周期挂钩,它在加载组件时首先处理。
这很简单,然后将该调用移至生命周期挂钩中,如下所示。
给class一个public变量即
public toolTipData: string;
(移入 OnInit)
this.planService.getAuditDetails(planId, fieldName, fieldValue)
.subscribe((auditDetail: AuditDetail) => {
this.tooTipData = auditDetail.toolTipInfo // (guessing at name)
this.auditDetail = auditDetail;
this.loadCompleted = true);
},
(errors) =>
{
console.log(errors) // api error status code.
}
});
在HTML中将工具提示值设置为
[ngbTooltip]="toolTipData"
这应该有助于适当地填充工具提示。
异步更改未显示,因为 NgbTooltip window 使用 ChangeDetectionStrategy.OnPush
并且触发更改检测的唯一方法是在关闭的工具提示上调用 open()
。
为了访问 NgbTooltip API:
添加对 NgbTooltip 的模板引用
<i #tooltip [ngbTooltip]="tipContent" (mouseenter)="refreshAuditDetail()" class="fas fa-info-circle fa-sm"></i>
将引用引入组件
@ViewChild('tooltip') tooltip: NgbTooltip;
黑客解决方案
加载数据后关闭并重新打开工具提示。如果用户在加载数据时已经离开工具提示,这可能会导致问题。
refreshAuditDetail() {
...
this.planService.getAuditDetails(planId, fieldName, fieldValue)
.subscribe((auditDetail: AuditDetail) => {
this.auditDetail = auditDetail;
this.tooltip.close();
this.tooltip.open();
}, () => {}, () => this.loadCompleted = true);
}
}
更好的解决方案
设置triggers="manual"。在 refreshAuditDetails
中调用 this.tooltip.open()
。添加一个 (mouseleave)
事件,取消来自 refreshAuditDetails
的订阅并调用 this.tooltip.close()
.
不幸的是 - 答案与时间无关。在发布之前,我忽略了 50 倍的外壳问题。在尝试实施收到的建议时,我终于注意到了问题。
HttpResponse 正在返回
{{UpdatedBy: XX, UpdatedAt: YY}) 而 AuditDetail 有 updatedBy 和 updatedAt 作为属性。它无法映射,这让我认为这是一个时间问题。
我是 angular 2+ 的新手,继承了一个不完整的项目。我的目标是创建一个工具提示,用于检查特定字段的审计详细信息并显示它们。一个例子可能是:
"Updated by Seth, on 8/18/18."
为此,我创建了一个组件 angular,它通过服务传回所有相关信息。通过查看 Web 调试器,我可以看到服务调用按预期工作。不幸的是,正在呈现的是带有以下不完整文本的工具提示:
"updated by , "
这是我的组件模板。
<ng-template #tipContent>
<span *ngIf="loadCompleted">Updated By {{ auditDetail.updatedBy }}, {{ auditDetail.updatedAt | amTimeAgo }}</span>
</ng-template>
<i [ngbTooltip]="tipContent" (mouseenter)="refreshAuditDetail()" class="fas fa-info-circle fa-sm"></i>
这是组件打字稿。
@Component({
selector: 'audit-tooltip',
templateUrl: './audit-tooltip.component.html',
styleUrls: ['./audit-tooltip.component.css']
})
export class AuditTooltipComponent {
@Input() plan: Plan;
@Input() fieldName: string;
auditDetail: AuditDetail;
loadCompleted: boolean = false;
constructor(private planService: PlanService) { }
refreshAuditDetail() {
var planId = this.plan.id;
var fieldName = this.fieldName;
var fieldValue = this.plan[this.fieldName];
this.loadCompleted = false;
this.planService.getAuditDetails(planId, fieldName, fieldValue)
.subscribe((auditDetail: AuditDetail) => {
console.log(auditDetail);
this.auditDetail = auditDetail;
}, () => {}, () => this.loadCompleted = true);
}
}
而且,如有必要,这里是我使用它的地方。
<h5 class="card-title">{{fieldLabel}}<audit-tooltip [fieldName]="fieldName" [plan]="plan"></audit-tooltip> </h5>
我错过了什么?
考虑使用 OnInit 生命周期挂钩,它在加载组件时首先处理。
这很简单,然后将该调用移至生命周期挂钩中,如下所示。
给class一个public变量即
public toolTipData: string;
(移入 OnInit)
this.planService.getAuditDetails(planId, fieldName, fieldValue)
.subscribe((auditDetail: AuditDetail) => {
this.tooTipData = auditDetail.toolTipInfo // (guessing at name)
this.auditDetail = auditDetail;
this.loadCompleted = true);
},
(errors) =>
{
console.log(errors) // api error status code.
}
});
在HTML中将工具提示值设置为
[ngbTooltip]="toolTipData"
这应该有助于适当地填充工具提示。
异步更改未显示,因为 NgbTooltip window 使用 ChangeDetectionStrategy.OnPush
并且触发更改检测的唯一方法是在关闭的工具提示上调用 open()
。
为了访问 NgbTooltip API:
添加对 NgbTooltip 的模板引用
<i #tooltip [ngbTooltip]="tipContent" (mouseenter)="refreshAuditDetail()" class="fas fa-info-circle fa-sm"></i>
将引用引入组件
@ViewChild('tooltip') tooltip: NgbTooltip;
黑客解决方案
加载数据后关闭并重新打开工具提示。如果用户在加载数据时已经离开工具提示,这可能会导致问题。
refreshAuditDetail() {
...
this.planService.getAuditDetails(planId, fieldName, fieldValue)
.subscribe((auditDetail: AuditDetail) => {
this.auditDetail = auditDetail;
this.tooltip.close();
this.tooltip.open();
}, () => {}, () => this.loadCompleted = true);
}
}
更好的解决方案
设置triggers="manual"。在 refreshAuditDetails
中调用 this.tooltip.open()
。添加一个 (mouseleave)
事件,取消来自 refreshAuditDetails
的订阅并调用 this.tooltip.close()
.
不幸的是 - 答案与时间无关。在发布之前,我忽略了 50 倍的外壳问题。在尝试实施收到的建议时,我终于注意到了问题。
HttpResponse 正在返回
{{UpdatedBy: XX, UpdatedAt: YY}) 而 AuditDetail 有 updatedBy 和 updatedAt 作为属性。它无法映射,这让我认为这是一个时间问题。