【问题标题】:core.js:6406 ERROR TypeError: Cannot read property 'id' of undefinedcore.js:6406 错误类型错误:无法读取未定义的属性“id”
【发布时间】:2020-07-22 20:55:42
【问题描述】:

我有一个 Angular 8 应用程序。还有一个创建功能。但我无法创建项目,因为 id 为空。

我当然搜索过这个。但我认为这是一个特定的案例。

所以这是触发函数的模板:

<button *ngIf="isNew" mat-raised-button color="primary" [appSubmitIfValid]="editItemForm" (valid)="save()" i18n>Create</button>

这是实际的功能:

  this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
        .subscribe(item => {
          this.item = item;
          this.dossierItems.unshift(item);
          this.sortDossierItems();
          this.isNew = false;
          form.enable();
          form.markAsPristine();
          this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
        }, error => this.handleError(error));

这是我的 router.ts:

  {
    path: ':dossierId',
    component: ViewComponent, children: [
    {  path: 'item/new/:dossierItemType', component: ItemComponent}
    ],
    resolve: {
      dossier: DossierResolver,
      dossierItems: DossierItemsResolver
    }
  },

所以我在这一行得到一个错误:

  this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)

idnull

但是我必须改变什么?

谢谢

更新:

这是添加新项目的链接:view.component.html:

 <ng-template mat-tab-label #interviews>
          <mat-icon class="interviews">speaker_notes</mat-icon>
          <span i18n>Interview reports</span>{{ dossierItemsCountString(itemTypes.Interview) }}
          <a [routerLink]="['../' , dossier.id , 'item' , 'new',  itemTypes.Interview]">
            <mat-icon class="add_box">add</mat-icon>
          </a>
        </ng-template>

问题在于路由。因为如果我这样做:

{
    path: ':dossierId/item/new/:dossierItemType', component: ItemComponent,
    resolve: {
      dossier: DossierResolver,
      dossierItems: DossierItemsResolver
    }
  },

然后我可以创建一个新项目。但这不是我想要的,因为新项目将被加载到新视图中。

这就是我有这个的原因:

 {
    path: ':dossierId',
    component: ViewComponent, children: [
    {  path: 'item/new/:dossierItemType', component: ItemComponent}
    ],
    resolve: {
      dossier: DossierResolver,
      dossierItems: DossierItemsResolver
    }
  },

但是档案每次都是空的。

这是完整的 item.component.ts 代码:

export class ItemComponent implements OnInit {
  itemTypes = DossierItemTypeDto;
  formBuilder = new FormBuilder();
  isNew = false;
  editItemForm: FormGroup;
  dossierItemId: string;
  item: DossierItemDto;
  dossierItems: DossierItemDto[];
  dossier: DossierDto;
  globalErrors: ValidationErrors;

  constructor(private dossierService: DossierService, private route: ActivatedRoute, private router: Router,
              private errorProcessor: ErrorProcessor) {

    this.dossier = this.route.snapshot.data.dossier;
    this.dossierItemId = this.route.snapshot.params.dossierItemId;
    this.isNew = this.dossierItemId === undefined;
    this.dossierItems = this.route.snapshot.data.dossierItems;

    if (this.isNew) {
      this.item =  {
        title: '',
        itemType: this.route.snapshot.params.dossierItemType,
        date: moment().format('Y-MM-DD'),
        createdAt: moment().format('Y-MM-DD'),
        body: '' };
    } else {
      this.item = this.dossierItems.find(i => i.id === this.dossierItemId);
    }
  }

  ngOnInit(): void {
    this.editItemForm = this.formBuilder.group({
      title: this.formBuilder.control(this.item.title, [Validators.required]),
      itemType: this.formBuilder.control(this.item.itemType, [Validators.required]),
      date: this.formBuilder.control(moment(this.item.date, 'Y-MM-DD'), [Validators.required]),
      body: this.formBuilder.control(this.item.body, [Validators.required, Validators.maxLength(2097152)])
    });
  }

  save(): void {
    const form = this.editItemForm;
    const dossierItemDto: DossierItemPostDto = {
      title: form.controls.title.value,
      itemType: form.controls.itemType.value,
      date: (form.controls.date.value as moment.Moment).format('Y-MM-DD'),
      body: form.controls.body.value
    };

    form.disable();

    if (!this.isNew) {
      this.dossierService.updateDossierItemById(this.dossier.id, this.item.id, dossierItemDto)
        .subscribe(item => {
          this.item = item;
          this.sortDossierItems();
          form.enable();
          form.markAsPristine();
          this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
        }, error => this.handleError(error));
    } else {
      this.dossierService.newDossierItem(this.dossier.id, dossierItemDto)
        .subscribe(item => {
          this.item = item;
          this.dossierItems.unshift(item);
          this.sortDossierItems();
          this.isNew = false;
          form.enable();
          form.markAsPristine();
          this.errorProcessor.openSuccessSnackBar($localize`Item is saved`);
        }, error => this.handleError(error));
    }
  }
}

但如果我试试这个:

  {
    path: ':dossierId',
    component: ViewComponent, children: [
    {  path: 'item/new/:dossierItemType', component: ItemComponent}
    ],
    resolve: {
      dossier: DossierResolver,
      dossierItems: DossierItemsResolver
    }
  },

好吧,这很奇怪,因为在这个:

ngOnInit(): void {
    this.route.params.subscribe((params: Params) => {
      this.dossier.id = params.dossierId;
    });

在调试器中。我第一次看到设置了id:

"06637e72-8915-4735-9400-4ef7705194ea"

但如果我执行 f8 则 id 为空:

 this.dossier.id = params.dossierId;

我的路线是这样的:

  {
    path: ':dossierId',
    component: ViewComponent, children: [
    {  path: 'item/new/:dossierItemType', component: ItemComponent}
    ],
    resolve: {
      dossier: DossierResolver,
      dossierItems: DossierItemsResolver
    }
  },

所以这被调用了两次:

 this.route.params.subscribe((params: Params) => {
      this.dossier.id = params.dossierId;
    });

不明白为什么

【问题讨论】:

  • 提供的代码不够好,无法调查。问题是您在将this.dossier 传递给服务时没有设置它。因此错误。提供完整的组件代码以进一步调试。你如何设置this.dossier
  • 有人有什么建议吗?谢谢
  • ItemComponent 有重复使用吗?网址在变吗?该值是从 url 中选取的。请检查确认
  • 我检查过,但只有我在 dossier.routing.module 和 dossier.module.ts 中

标签: javascript angular typescript angular2-routing


【解决方案1】:

你可以试试paramsInheritanceStrategy 吗?

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    paramsInheritanceStrategy: 'always'
})],
  exports: [RouterModule]
})
export class AppRoutingModule { }

您还需要捕获父路由参数

【讨论】:

    【解决方案2】:

    下面的代码对我有用:

    在 Angular 项目的 tsconfig.json 中

    {
      ...
      "angularCompilerOptions": {
        "enableIvy": false
      }
    }

    【讨论】:

      猜你喜欢
      • 2020-03-02
      • 2021-04-05
      • 2021-05-20
      • 1970-01-01
      • 2021-03-12
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多