【问题标题】:Function inside a function is not a function and is undefined函数内部的函数不是函数并且是未定义的
【发布时间】:2019-03-01 12:19:41
【问题描述】:

概述

我正在学习 Angular 和 JHipster,我正在尝试获取集合中对象的 id。

我正在尝试使用 trackBy 获取 id,但出现此错误:

[Error] ERROR – TypeError: this.cargarElementosFoda is not a function. (In 'this.cargarElementosFoda(item.id)', 'this.cargarElementosFoda' is undefined)

    TypeError: this.cargarElementosFoda is not a function. (In 'this.cargarElementosFoda(item.id)', 'this.cargarElementosFoda' is undefined)trackIdcheckdiffngDoCheckcheckAndUpdateDirectiveInlinedebugCheckAndUpdateNodedebugCheckDirectivesFn(función anónima)checkAndUpdateViewcallViewActionexecEmbeddedViewsActioncheckAndUpdateViewcallViewActionexecComponentViewsActioncheckAndUpdateViewcallViewActionexecEmbeddedViewsActioncheckAndUpdateViewcallViewActionexecComponentViewsActioncheckAndUpdateViewcallWithDebugContextdetectChangesforEachtick(función anónima)onInvokerunnext(función anónima)__tryOrUnsubnext_nextnextnextemitcheckStableonLeaveonInvokeTaskrunTaskinvokeTaskinvokeTaskglobalZoneAwareCallback
        error
        View_PlanEstrategicoDetailComponent_1 (PlanEstrategicoDetailComponent.ngfactory.js:337)
        logError (core.js:12446)
        (función anónima)
        handleError (core.js:1922)
        run (zone.js:137)
        tick (core.js:5374)
        (función anónima) (core.js:5210:110)
        onInvoke (core.js:4343)
        run (zone.js:137)
        next (core.js:5210:85)
        (función anónima) (core.js:3993)
        __tryOrUnsub (Subscriber.js:262)
        next (Subscriber.js:200)
        _next (Subscriber.js:138)
        next (Subscriber.js:102)
        next (Subject.js:64)
        emit (core.js:3985)
        checkStable (core.js:4312)
        onLeave (core.js:4379)
        onInvokeTask (core.js:4337)
        runTask (zone.js:187)
        invokeTask (zone.js:495)
        invokeTask (zone.js:1539)
        globalZoneAwareCallback (zone.js:1576)

我不知道为什么会这样,因为我的所有其他功能都运行良好。

这是 TS 组件:

      import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';
import { JhiEventManager, JhiParseLinks, JhiAlertService } from 'ng-jhipster';

import { DiagnosticoFodaService } from 'app/entities/diagnostico-foda';
import { IPlanEstrategico } from 'app/shared/model/plan-estrategico.model';
import { IDiagnosticoFoda } from 'app/shared/model/diagnostico-foda.model';
import {IElementosDiagnosticoFoda} from 'app/shared/model/elementos-diagnostico-foda.model';
import { ElementosDiagnosticoFodaService } from 'app/entities/elementos-diagnostico-foda';
@Component({
    selector: 'sigem-plan-estrategico-detail',
    templateUrl: './plan-estrategico-detail.component.html'
})
export class PlanEstrategicoDetailComponent implements OnInit {
    planEstrategico: IPlanEstrategico; 
    diagnosticoFodas: IDiagnosticoFoda[];
    elementosDiagnosticoFodas : IElementosDiagnosticoFoda[];
    elementosFodas: IDiagnosticoFoda[];
    idPlan : number;

    constructor(
        private jhiAlertService: JhiAlertService, 
        private activatedRoute: ActivatedRoute,
        private diagnosticoFodaService: DiagnosticoFodaService,
        private elementosDiagnosticoFodaService : ElementosDiagnosticoFodaService) {}

    ngOnInit() {
        this.activatedRoute.data.subscribe(({ planEstrategico }) => {
            this.planEstrategico = planEstrategico;
            this.idPlan = planEstrategico.id; 
            this.cargarAnaliziFoda(this.idPlan);
        });

    }

    previousState() {
        window.history.back();
    }
    private onError(errorMessage: string) {
        this.jhiAlertService.error(errorMessage, null, null);
    }

    cargarAnaliziFoda(id){
        this.diagnosticoFodaService.findByPlan(id).subscribe(
            (res: HttpResponse<IDiagnosticoFoda[]>) => {
                this.diagnosticoFodas = res.body;   
            },
            (res: HttpErrorResponse) => this.onError(res.message)
        );
    }
    cargarElementosFoda(id_foda){ 
        /*this.elementosDiagnosticoFodaService.findByFODA(id_foda).subscribe(
            (res: HttpResponse<IElementosDiagnosticoFoda[]>) => {
                this.elementosDiagnosticoFodas = res.body;   
                console.log(this.elementosDiagnosticoFodas);
            },
            (res: HttpErrorResponse) => this.onError(res.message)
        );*/
    }
    trackId(index: number, item: IDiagnosticoFoda) {
        console.log('el id de este diagnostico foda es' + item.id);
        this.cargarElementosFoda(item.id); 
    }


}

和 HTML 组件:

这是我通过 id 调用 track 的 html 部分

<ngb-panel  *ngFor="let diagnosticoFoda of diagnosticoFodas;trackBy: trackId">
<ng-template  ngbPanelTitle>
<span > Diagnostico FODA {{diagnosticoFoda.nombre}} 
</span>
</ng-template>

备注

  • 我对 Angular、TypeScript 和 Jhipster 非常陌生。
  • 如果我遗漏了重要内容,请在评论中告诉我,我会添加到问题中。
  • 我只是想得到diagnosticoFoda.id 所以也许更好 trackBy 函数的方式。

【问题讨论】:

  • 你能显示代码所在的完整文件吗?
  • @AGhanima 抱歉,我用完整代码更新了任务。
  • 我们需要知道这发生在哪里。我假设您的模板中的某些内容是直接调用 trackId(调用 cargarElementosFoda)或 cargarElementosFoda。但是您发布的代码中没有任何内容实际上会导致 cargarElementosFoda 被调用。
  • @NightCabbage 是的,在 html 模板中,我有一个 Collapse 和不同的 ngb-panels 用于一些许多数据,但这里重要的是 FODA 的一个,所以让我将其添加到问题中。跨度>

标签: angular typescript


【解决方案1】:

问题

我的猜测是事件处理程序正在调用trackId 方法。如果我们从事件处理程序调用方法,则该方法不再将其this 绑定到该类的实例。随着 this 不再绑定到类的实例,cargarElementosFoda 方法未定义,这就是您的错误状态。

一个解决方案

trackId 变成an arrow function 而不是方法。这将确保 this 绑定到该类的实例,即使从事件调用箭头函数也是如此。

trackId = (index: number, item: IDiagnosticoFoda) => {
    console.log('el id de este diagnostico foda es' + item.id);
    this.cargarElementosFoda(item.id); 
}

更多详情

这是一个简化的示例,其中一个事件调用箭头函数,另一个事件调用方法。请注意,只有在从该类的实例调用该方法时,该方法才会将 this 绑定到该类。

class Foo {

  someMethod() {
    console.log('someMethod:' + (this instanceof Foo));
  }

  someArrowFunction = () => {
    console.log('someArrowFunction:' + (this instanceof Foo));
  };
}

const foo = new Foo();

// when called from an instance of the class,
// both the arrow function and the method are bound to an instance of Foo
foo.someArrowFunction();
foo.someMethod();

// when not called from an event
// the arrow function remains bound to the instance of Foo
document
  .getElementById('btn1')
  .addEventListener("click", foo.someArrowFunction);

// when not called from an event
// the  method is no longer bound the instance of Foo
document
  .getElementById('btn2')
  .addEventListener("click", foo.someMethod);
<button id="btn1">Invoke Arrow Function</button>
<button id="btn2">Invoke Method</button>

【讨论】:

  • 谢谢你,它真的很有启发性并解决了我的问题。
  • 不客气。我很高兴听到它有帮助。这对我来说意义重大。
  • 是的,实际上我的老师知道发生了,他学会了,最后我没有使用轨道 ID 来调用该方法,但这在我学习 angular 和 typeScript 的漫长道路上仍然是一个参考所以谢谢你的时间和例子。
  • 影响太大了!这很有趣。
猜你喜欢
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多