Angular5: необходимо предотвратить рендеринг ngbTooltip до того, как данные будут возвращены из наблюдаемого - PullRequest
0 голосов
/ 27 августа 2018

Я новичок в angular 2+ и унаследовал незавершенный проект. Моя цель - создать всплывающую подсказку, которая проверяет детали аудита по конкретному полю и отображает их. Примером может быть:

"Updated by Seth, on 8/18/18."

Для этого я создал угловой компонент, который передает всю необходимую информацию обратно через сервис. Я вижу, что вызов службы работает как обычно, посмотрев в веб-отладчик. К сожалению, под рендерингом понимается всплывающая подсказка со следующим неполным текстом:

 "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>

Чего мне не хватает?

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Асинхронные изменения не отображаются, потому что в окне NgbTooltip используется ChangeDetectionStrategy.OnPush, и единственный способ вызвать обнаружение изменений - это вызов open() для закрытой всплывающей подсказки.

Для доступа к API NgbTooltip:

Добавить шаблон ссылки на NgbTooltip

<i #tooltip [ngbTooltip]="tipContent" (mouseenter)="refreshAuditDetail()" class="fas fa-info-circle fa-sm"></i>

Ввести ссылку в компонент

@ViewChild('tooltip') tooltip: NgbTooltip;

Hacky Solution

Закройте и снова откройте всплывающую подсказку после загрузки данных. Это может вызвать проблемы, если пользователь уже вышел из всплывающей подсказки к моменту загрузки данных.

 refreshAuditDetail() {
  ...
  this.planService.getAuditDetails(planId, fieldName, fieldValue)
    .subscribe((auditDetail: AuditDetail) => {
      this.auditDetail = auditDetail;
      this.tooltip.close();
      this.tooltip.open();
    }, () => {}, () => this.loadCompleted = true);
  }
}

Лучшее решение

Set triggers = "manual" . Позвоните this.tooltip.open() в refreshAuditDetails. Добавьте событие (mouseleave), которое отменяет подписку с refreshAuditDetails и вызывает this.tooltip.close().

0 голосов
/ 31 августа 2018

К сожалению, ответ не был связан с выбором времени. Я пропустил проблему с кожухом в 50 раз, прежде чем опубликовать. Пытаясь реализовать полученные предложения, я наконец-то заметил проблему.

HttpResponse возвращался

{{ U pdatedBy: XX, U pdatedAt: YY}), тогда как AuditDetail имеет u pdatedBy и u pdatedAt в качестве свойств , он не смог отобразить карту, из-за чего это выглядело так, как я думал, было проблемой синхронизации.

0 голосов
/ 29 августа 2018

Изучите использование ловушки жизненного цикла OnInit, которая обрабатывается первой при загрузке компонента.

Документация для ngOnInit

Это достаточно просто, затем переместите этот вызов в службу, как показано ниже, в хук жизненного цикла.

Дайте классу общедоступную переменную, т.е.

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"

Это должно помочь правильно заполнить подсказку.

...