在使用ng-zorro的上传文件组件时,因为要自定义上传方式,找到他的一个属性,需要穿对应的方法进去让他执行,于是就写了一个上传方法:

/**
     * 导入学生信息
     */
    importItems(item: UploadXHRArgs) {
        const formData = new FormData();
        formData.append('multipartFile', item.file as any);
        return this.studentService.batchImport(formData).subscribe(() => {
            this.reloadData();
            this.message.create('success', '上传成功!');
        }, () => {
            this.message.create('error', '上传失败!');
        });
    }

结果一上传,居然报了个batchImport' of undefined的错.我把this对象打出来后,发现this对象是这样的:
clipboard.png
而我们组件对象应该是这样的:

clipboard.png
打出来后明白了,应该是将函数传递过去后执行环境变了,this对象也就不同了,但是这要怎么解决呢?
回文档仔细查看,发现了忽略的字:

clipboard.png

他是要求用labmda表达式的,改成labmda表达式:

importItems = (file: FormData) => {
        return this.studentService.batchImport(file).subscribe(() => {
            this.reloadData();
            this.message.create('success', '上传成功!');
        }, () => {
            this.message.create('error', '上传失败!');
        });
    }

结果成功了.

上网一搜,发现了labmda表达式与普通函数的不同:

箭头函数和普通函数有一个微妙的区别,那就是箭头函数没有它们自己的 this,箭头函数中的 this 值始终来自闭包所在的作用域。
如果你在箭头函数引用了this、arguments或者参数之外的变量,那它们一定不是箭头函数本身包含的,而是从父级作用域继承的
原来如此,箭头函数本身就为一个闭包操作,我们使用箭头函数之后就不用写闭包,也能保留我们想要的作用域了。

用普通函数定义的话,虽然是在studentIndexComponent定义的,但执行环境却是在NgUploadBthComponent里,所以this指向的时NgUploadBthComponent对象:
clipboard.png
用lambda表达式定义的函数,会把this对象从父级作用域继承继承而来,使用时自然会使用集成的父类对象:

clipboard.png
顺带一提,使用闭包的写法:

/**
     * 导入学生信息
     */
    importItems() {
        const self = this;
        return function(item: UploadXHRArgs) {
            const formData = new FormData();
            formData.append('multipartFile', item.file as any);
            return this.studentService.batchImport(formData).subscribe(() => {
                self.reloadData();
                self.message.create('success', '上传成功!');
            }, () => {
                self.message.create('error', '上传失败!');
            });
        };
    }

鲸冬香
456 声望27 粉丝