【问题标题】:Angular 2 Inline template cannot read property of undefinedAngular 2内联模板无法读取未定义的属性
【发布时间】:2017-04-02 18:22:33
【问题描述】:

我正在尝试根据单击选项卡集上的图标在选项卡正文部分中呈现数据。这是我最初成功渲染的视图的屏幕截图:

但是当我单击一个新的标签集图标将数据加载到标签正文部分时,我得到以下异常:

TypeError: Cannot read property 'category' of undefined
at CompiledTemplate.proxyViewClass.View_DnDMiniCardGroupComponent0.detectChangesInternal (/PaletteSchemaModule/DnDMiniCardGroupComponent/component.ngfactory.js:144)
at CompiledTemplate.proxyViewClass.AppView.detectChanges (view.js:425)
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (view.js:620)
at CompiledTemplate.proxyViewClass.AppView.internalDetectChanges (view.js:410)
at CompiledTemplate.proxyViewClass.View_TabCommunityComponent0.detectChangesInternal (/PaletteSchemaModule/TabCommunityComponent/component.ngfactory.js:89)
at CompiledTemplate.proxyViewClass.AppView.detectChanges (view.js:425)
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (view.js:620)
at CompiledTemplate.proxyViewClass.AppView.internalDetectChanges (view.js:410)
at View_TypesContentComponent2.detectChangesInternal (/PaletteSchemaModule/TypesContentComponent/component.ngfactory.js:190)
at View_TypesContentComponent2.AppView.detectChanges (view.js:425)
at View_TypesContentComponent2.DebugAppView.detectChanges (view.js:620)
at ViewContainer.detectChangesInNestedViews (view_container.js:67)
at CompiledTemplate.proxyViewClass.View_TypesContentComponent0.detectChangesInternal (/PaletteSchemaModule/TypesContentComponent/component.ngfactory.js:592)
at CompiledTemplate.proxyViewClass.AppView.detectChanges (view.js:425)
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (view.js:620)

这是我的标签集模板的一部分,它显示基于ngSwitchngSwitchCase 的标签内容主体:

<div class="schema-palette" [ngSwitch]="tabId">
    <myapp-base-palette *ngSwitchCase="'T'">
        <myapp-tabset [tabType]="'T'" (onTabSelected)="tabChanged($event)" palette-tabset></myapp-tabset>
        <myapp-tab-community palette-content-region></myapp-tab-community>
    </myapp-base-palette>
</div>

这是我的myapp-tab-community 组件模板:

<div class="community-buffer" ngFor="let miniCardGrp of miniCardGrps; let i = index">
  <div style="height:5px" *ngIf="i === 0"></div>
  <myapp-dnd-mini-card-group [miniCardGrp]="miniCardGrp"></myapp-dnd-mini-card-group>
</div>

这里是myapp-tab-community 组件打字稿:

import { Component, OnInit, AfterViewInit } from '@angular/core';

import { PalettesService } from '../../palettes.service';
import { MiniCardGroup } from '../../palettes.helpers';
import { DnDMiniCardGroupComponent } from '../../shared/dnd-mini-card-group/dnd-mini-card-group.component';

@Component({
  selector: 'myapp-tab-community',
  templateUrl: './tab-community.component.html',
  styleUrls: ['./tab-community.component.scss'],
  providers: [PalettesService]
})
export class TabCommunityComponent implements OnInit, AfterViewInit {

  miniCardGrps: MiniCardGroup[];

  constructor(private palettesService: PalettesService) {}

  ngOnInit() {
    this.miniCardGrps = [];
    this.miniCardGrps = this.palettesService.getTemplateTypes();

    // DATA IS SUCCESSFULLY RETRIEVED
    console.log('TabCommunityComponent.ngOnInit = ' + JSON.stringify(this.miniCardGrps));
  }

  ngAfterViewInit() {
    // ERROR BLOCKS EVALUATION
    console.log('TabCommunityComponent.ngAfterViewInit = ' + JSON.stringify(this.miniCardGrps));
  }

  trackByMiniCardGroup(index: number, miniCardGrp: MiniCardGroup) {
    return miniCardGrp.category;
  }

}

应呈现myapp-dnd-mini-card-group 组件数组,但从其模板中抛出错误。

模板文件:

<div class="mini-card-grp-collapse">
  <div class="mini-card-grp-collapse-row">
    <div class="mini-card-grp-title">
      <a data-toggle="collapse" [href]="href" aria-expanded="true" attr.aria-controls="{{ ariaControls }}">
        <!-- THIS LINE THROWS -->
        <md-icon class="white-text md-16">play_arrow</md-icon>{{ miniCardGrp.category }}
      </a>
    </div>
    <div class="mini-card-grp-title-helper">
      <md-icon class="white-text md-24">help_outline</md-icon>
    </div>
  </div>
</div>
<div class="collapse in" [id]="id">
  <div class="mini-card-wrapper" *ngFor="let miniCard of miniCardGrp.miniCards">
    <myapp-dnd-mini-card [miniCard]="miniCard"></myapp-dnd-mini-card>
  </div>
</div>

现在是打字稿文件:

import { Component, OnInit, AfterViewInit, Input } from '@angular/core';

import { MathHelper } from '../../../../utils/math';
import { MiniCardGroup } from '../../palettes.helpers';

import { DndMiniCardComponent } from '../dnd-mini-card/dnd-mini-card.component';

@Component({
  selector: 'myapp-dnd-mini-card-group',
  templateUrl: './dnd-mini-card-group.component.html',
  styleUrls: ['./dnd-mini-card-group.component.scss']
})
export class DnDMiniCardGroupComponent implements OnInit, AfterViewInit 
{

  @Input() miniCardGrp: MiniCardGroup;
  @Input() href: string;
  @Input() id: string;
  @Input() ariaControls: string;

  constructor() {
    let mathHelper = new MathHelper();
    let random$ = mathHelper.getRandomNumberString();
    this.id = random$;
    this.href = '#' + random$;
    this.ariaControls = random$;
  }

  ngOnInit() {
    // IS UNDEFINED
    console.log('DnDMiniCardGroupComponent.ngOnInit = ' + JSON.stringify(this.miniCardGrp));
  }

  ngAfterViewInit() {
    // IS NEVER REACHED
    console.log('DnDMiniCardGroupComponent.ngAfterViewInit = ' + JSON.stringify(this.miniCardGrp));
  }

}

我在这里做错了什么?

根据要求,mini-card-group 组件如下所示:

<div class="btn-grp-collapse">
  <div class="btn-grp-collapse-row">
    <div class="btn-grp-title">
      <a data-toggle="collapse" [href]="href" aria-expanded="true" attr.aria-controls="{{ ariaControls }}">
        <md-icon class="white-text md-16">play_arrow</md-icon>{{ dndButtonGrp.title }}
      </a>
    </div>
    <div class="btn-grp-title-helper">
      <md-icon class="white-text md-24">help_outline</md-icon>
    </div>
  </div>
</div>
<div class="collapse in" [id]="id">
  <div class="btn-wrapper" *ngFor="let dndButton of dndButtonGrp.dndButtons">
    <myapp-dnd-button [dndButton]="dndButton"></myapp-dnd-button>
  </div>
</div>

它的打字稿文件:

import { Component, Input, OnInit } from '@angular/core';

import { MathHelper } from '../../../../utils/math'
import { DnDButtonGroup } from './dnd-button-group.helpers';

import { DndButtonComponent } from '../dnd-button/dnd-button.component';

@Component({
  selector: 'myapp-dnd-button-group',
  templateUrl: './dnd-button-group.component.html',
  styleUrls: ['./dnd-button-group.component.scss']
})
export class DnDButtonGroupComponent implements OnInit {

  @Input() dndButtonGrp: DnDButtonGroup;
  @Input() href: string;
  @Input() id: string;
  @Input() ariaControls: string;

  constructor() {
    let mathHelper = new MathHelper();
    let random$ = mathHelper.getRandomNumberString();
    this.id = random$;
    this.href = '#' + random$;
    this.ariaControls = random$;
  }

  ngOnInit() {}

}

【问题讨论】:

  • 你试过{{ miniCardGrp?.category }}吗?
  • 我试过这个和 *ngIf="miniCardGrp" 但即使我确认我的服务返回数据,它也不会呈现。
  • 你是怎么确认的?
  • Chrome 控制台输出:DnDMiniCardGroupComponent.ngOnInit = undefined dnd-mini-card-group.component.ts:33 DnDMiniCardGroupComponent.ngAfterViewInit = undefined
  • 未定义..

标签: javascript angular templates


【解决方案1】:

调用服务时数据可能还没到,需要订阅服务获取数据

ngOnInit() {
    this.palettesService
    .getTemplateTypes()
    .subscribe(data => this.miniCardGrps = data);
}

【讨论】:

  • 我认为你的权利,但我必须重新连接我的服务。今晚会回到这个。会及时更新。感谢您的帮助罗曼。
  • 这对我不起作用。我可以在组件的构造函数中成功检索我的 JSON 有效负载并将其分配给 this.miniCardGrps。但是它在构造函数之外失去了它的价值,并且模板没有被渲染,即使在管道异步时也是如此。我在这里错过了什么?
  • 你的错误是在构造函数中做。查看我的更新。
【解决方案2】:

我需要实现动态组件来呈现每个选项卡的内容。以下是完整背景的相关链接:

https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    相关资源
    最近更新 更多