【问题标题】:Angular2 'this' is undefinedAngular2 'this' 未定义
【发布时间】:2016-08-21 09:52:14
【问题描述】:

我的代码如下所示:

export class CRListComponent extends ListComponent<CR> implements OnInit {

    constructor(
        private router: Router,
        private crService: CRService) {
        super();
    }

    ngOnInit():any {
        this.getCount(new Object(), this.crService.getCount);
    }

ListComponent 的代码是这样的

@Component({})
export abstract class ListComponent<T extends Listable> {

    protected getCount(event: any, countFunction: Function){
        let filters = this.parseFilters(event.filters);
        countFunction(filters)
            .subscribe(
                count => {
                    this.totalItems = count;
                },
                error => console.log(error)
            );
    }

来自 CRService 的相应服务代码片段是这样的:

getCount(filters) {
    var queryParams = JSON.stringify(
        {
            c : 'true',
            q : filters
        }
    );

    return this.createQuery(queryParams)
        .map(res => res.json())
        .catch(this.handleError);
}

现在当我的ngOnInit() 运行时,我得到一个错误:

angular2.dev.js:23925 例外:类型错误:无法读取属性 'createQuery' of undefined in [null]

原始异常: TypeError:无法读取未定义的属性“createQuery”

所以基本上,return this.createQuery(queryParams) 语句中的this 将为空。有谁知道这怎么可能?

【问题讨论】:

  • 你认为this.createQuery为什么存在?
  • 您的 2 个班级缺少右括号是否“正常”?
  • 我只是省略了不必要的部分,否则代码在语法上是正确的。 :) 问题不在于.createQuery,而在于this 本身。

标签: javascript angular angular2-services


【解决方案1】:

问题出在这里:

gOnInit():any {
    this.getCount(new Object(), this.crService.getCount); // <----
}

因为你引用了一个对象之外的函数。你可以在上面使用bind 方法:

this.getCount(new Object(), this.crService.getCount.bind(this.crService));

或将其包装成箭头函数:

this.getCount(new Object(), (filters) => {
  return this.crService.getCount(filters));
});

第二种方法是首选方法,因为它允许保留类型。有关详细信息,请参阅此页面:

【讨论】:

  • 谢谢,它似乎工作!有没有办法在 HTML 模板绑定中做到这一点?我的意思是,我有以下代码:(onLazyLoad)="loadItems($event, this.crService.getCRs)" 我也可以将其转换为类似的东西吗? (onLazyLoad)="loadItems($event, (page, n, sortField, sortOrder, filters) =&gt; { return this.crService.getCRs(page, n, sortField, sortOrder, filters)})"
  • 太棒了!您不需要在模板中使用 this 关键字。也就是说,我会使用中间级别。我的意思是:在 loadItems 方法中使用 this.crService.getCRs...
  • 很好,我也得到了这个解决方案。这似乎也比在我的 HTML 模板中嵌入如此丑陋的代码要干净得多。谢谢您的帮助! :)
【解决方案2】:

为了修复这个错误,我将所有导致错误的函数中的所有内脏都拉出来,然后将其扔到另一个函数中,然后错误就消失了。

示例:

我有这个函数,里面有一些代码

this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
  // bunch of code to evaluate click event
  // this is the code that had the "this" undefined error
});

我把代码拉出来放在一个外部公共函数中,这是完成的代码:

this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
  this.evaluateClick(event);
});

evaluateClick(evt: MouseEvent){
    // all the code I yanked out from above
}

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 2016-11-09
    • 2016-09-12
    • 1970-01-01
    • 2020-01-21
    • 2018-04-09
    • 2016-01-27
    相关资源
    最近更新 更多