在数据出现之前在视图中加载指令的问题
Issue of directive loading in view before data is present
视图在来自调用的数据之前加载并传递给 Angular 中的指令 4.
我进行了一些调试,但无法解决这个问题,我猜问题是在加载视图之前数据不存在。
错误:
ERROR TypeError: Cannot read property 'type' of undefined
at EngagementFullviewComponent.dataFortooltip (engagement-
fullview.component.ts:575)
at Object.eval [as updateDirectives] (EngagementFullviewComponent.html:198)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13067)
at checkAndUpdateView (core.es5.js:12251)
at callViewAction (core.es5.js:12599)
at execEmbeddedViewsAction (core.es5.js:12557)
at checkAndUpdateView (core.es5.js:12252)
at callViewAction (core.es5.js:12599)
at execEmbeddedViewsAction (core.es5.js:12557)
at checkAndUpdateView (core.es5.js:12252)
Html 带指令
[工具提示是指令]。
我得到的 "row" 来自 http 调用,然后处理并传递给 tooltip 指令以在 html
中呈现
<img src="assets/images/restriction.png" tooltip="{{dataFortooltip(row)}}">
ts 文件
dataFortooltip(data){
let concatData;
debugger;
if(data.restrictions){
for(let i=0;i<=data.restrictions.length;i++){
concatData += data.restrictions[i].type
}
return concatData;
}
tooltip.directive.ts
import { Directive, Input, ElementRef, HostListener, Renderer2 } from
'@angular/core';
@Directive({
selector: '[tooltip]'
})
export class TooltipDirective {
@Input('tooltip') tooltipTitle: string;
@Input() placement: string;
@Input() delay;
tooltip: HTMLElement;
offset = 10;
constructor(private el: ElementRef, private renderer: Renderer2) { }
@HostListener('mouseenter') onMouseEnter() {
if (!this.tooltip) { this.show(); }
}
@HostListener('mouseleave') onMouseLeave() {
if (this.tooltip) { this.hide(); }
}
show() {
this.create();
this.setPosition();
this.renderer.addClass(this.tooltip, 'ng-tooltip-show');
}
hide() {
this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');
//window.setTimeout(() => {
this.renderer.removeChild(document.body, this.tooltip);
this.tooltip = null;
//}, this.delay);
}
create() {
this.tooltip = this.renderer.createElement('span');
this.renderer.appendChild(
this.tooltip,
this.renderer.createText(this.tooltipTitle) // textNode
);
this.renderer.appendChild(document.body, this.tooltip);
// this.renderer.appendChild(this.el.nativeElement, this.tooltip);
this.renderer.addClass(this.tooltip, 'ng-tooltip');
this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
// delay
this.renderer.setStyle(this.tooltip, '-webkit-transition', `opacity
${this.delay}ms`);
this.renderer.setStyle(this.tooltip, '-moz-transition', `opacity
${this.delay}ms`);
this.renderer.setStyle(this.tooltip, '-o-transition', `opacity
${this.delay}ms`);
this.renderer.setStyle(this.tooltip, 'transition', `opacity
${this.delay}ms`);
}
setPosition() {
const hostPos = this.el.nativeElement.getBoundingClientRect();
const tooltipPos = this.tooltip.getBoundingClientRect();
const scrollPos = window.pageYOffset ||
document.documentElement.scrollTop || document.body.scrollTop || 0;
let
top, left;
if (this.placement === 'top') {
top = hostPos.top - tooltipPos.height - this.offset;
left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
}
if (this.placement === 'bottom') {
top = hostPos.bottom + this.offset;
left = hostPos.left + (hostPos.width -
tooltipPos.width) / 2;
}
if (this.placement === 'left') {
top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
left = hostPos.left - tooltipPos.width - this.offset;
}
if (this.placement === 'right') {
top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
left = hostPos.right + this.offset;
}
this.renderer.setStyle(this.tooltip, 'top', `${top + scrollPos}px`);
this.renderer.setStyle(this.tooltip, 'left', `${left}px`);
}
}
问题不在于指令,而是在 engagement- fullview.component.ts
的第 575 行:
concatData += data.restrictions[i].type
data.restrictions[i]
为空 - 修复此问题,您将获得解决方案。
视图在来自调用的数据之前加载并传递给 Angular 中的指令 4.
我进行了一些调试,但无法解决这个问题,我猜问题是在加载视图之前数据不存在。
错误:
ERROR TypeError: Cannot read property 'type' of undefined
at EngagementFullviewComponent.dataFortooltip (engagement-
fullview.component.ts:575)
at Object.eval [as updateDirectives] (EngagementFullviewComponent.html:198)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13067)
at checkAndUpdateView (core.es5.js:12251)
at callViewAction (core.es5.js:12599)
at execEmbeddedViewsAction (core.es5.js:12557)
at checkAndUpdateView (core.es5.js:12252)
at callViewAction (core.es5.js:12599)
at execEmbeddedViewsAction (core.es5.js:12557)
at checkAndUpdateView (core.es5.js:12252)
Html 带指令 [工具提示是指令]。 我得到的 "row" 来自 http 调用,然后处理并传递给 tooltip 指令以在 html
中呈现<img src="assets/images/restriction.png" tooltip="{{dataFortooltip(row)}}">
ts 文件
dataFortooltip(data){
let concatData;
debugger;
if(data.restrictions){
for(let i=0;i<=data.restrictions.length;i++){
concatData += data.restrictions[i].type
}
return concatData;
}
tooltip.directive.ts
import { Directive, Input, ElementRef, HostListener, Renderer2 } from
'@angular/core';
@Directive({
selector: '[tooltip]'
})
export class TooltipDirective {
@Input('tooltip') tooltipTitle: string;
@Input() placement: string;
@Input() delay;
tooltip: HTMLElement;
offset = 10;
constructor(private el: ElementRef, private renderer: Renderer2) { }
@HostListener('mouseenter') onMouseEnter() {
if (!this.tooltip) { this.show(); }
}
@HostListener('mouseleave') onMouseLeave() {
if (this.tooltip) { this.hide(); }
}
show() {
this.create();
this.setPosition();
this.renderer.addClass(this.tooltip, 'ng-tooltip-show');
}
hide() {
this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');
//window.setTimeout(() => {
this.renderer.removeChild(document.body, this.tooltip);
this.tooltip = null;
//}, this.delay);
}
create() {
this.tooltip = this.renderer.createElement('span');
this.renderer.appendChild(
this.tooltip,
this.renderer.createText(this.tooltipTitle) // textNode
);
this.renderer.appendChild(document.body, this.tooltip);
// this.renderer.appendChild(this.el.nativeElement, this.tooltip);
this.renderer.addClass(this.tooltip, 'ng-tooltip');
this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
// delay
this.renderer.setStyle(this.tooltip, '-webkit-transition', `opacity
${this.delay}ms`);
this.renderer.setStyle(this.tooltip, '-moz-transition', `opacity
${this.delay}ms`);
this.renderer.setStyle(this.tooltip, '-o-transition', `opacity
${this.delay}ms`);
this.renderer.setStyle(this.tooltip, 'transition', `opacity
${this.delay}ms`);
}
setPosition() {
const hostPos = this.el.nativeElement.getBoundingClientRect();
const tooltipPos = this.tooltip.getBoundingClientRect();
const scrollPos = window.pageYOffset ||
document.documentElement.scrollTop || document.body.scrollTop || 0;
let
top, left;
if (this.placement === 'top') {
top = hostPos.top - tooltipPos.height - this.offset;
left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
}
if (this.placement === 'bottom') {
top = hostPos.bottom + this.offset;
left = hostPos.left + (hostPos.width -
tooltipPos.width) / 2;
}
if (this.placement === 'left') {
top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
left = hostPos.left - tooltipPos.width - this.offset;
}
if (this.placement === 'right') {
top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
left = hostPos.right + this.offset;
}
this.renderer.setStyle(this.tooltip, 'top', `${top + scrollPos}px`);
this.renderer.setStyle(this.tooltip, 'left', `${left}px`);
}
}
问题不在于指令,而是在 engagement- fullview.component.ts
的第 575 行:
concatData += data.restrictions[i].type
data.restrictions[i]
为空 - 修复此问题,您将获得解决方案。