angular - 为什么其中一个管道正确引用了“this”而另一个没有?
问题描述
我正在构建一个可管道化的运算符,但发现自己对这两种方法排列之间的区别究竟是什么视而不见。一个有效,另一个无效。
export class CrudService {
constructor(private datastore: DatastoreService,
private http: HttpClient) { }
// Making the operator an attribute on the object
// instance allows `this.datastore` to work as expected ✅
upsertResponse = (source: any) =>
source.pipe(
map((data: any) => {
this.datastore.validate_and_upsert(data)
return true
})
)
}
export class CrudService {
constructor(private datastore: DatastoreService,
private http: HttpClient) { }
// Making the operator an instance method means that
// `this.datastore` throws an error ❌
upsertResponse(source: any){
return source.pipe(
map((data: any) => {
this.datastore.validate_and_upsert(data)
return true
})
)
}
}
为什么this.datastore.validate_and_upsert
一个有效,另一个无效?
根据版主建议编辑
这个问题已被改写,以使其更密切地关注导致问题的原因。
解决方案
它们都是可管道的,但只有一个可以访问this
类的上下文。我想你可以猜到是哪一个。作为属性制作的那个。有一种方法可以使用.bind(this)
:
readonly obs$ = this.http.get().pipe(
this.upsertResponse.bind(this)
);
upsertResponse<T>(source: Observable<T>){
return source.pipe(
tap((data) => this.datastore.validate_and_upsert(data)),
mapTo(true)
);
}
或者仅使用整个可观察对象作为源,但它不再是管道:
readonly obs$ = this.upsertResponse(this.http.get());
但明智的意见,我相信你问题中的属性方式更好。
readonly upsertResponse = //...;
这样您就不必担心 this 上下文,而且很明显该方法是一个实用方法。
仅供参考,当您添加事件侦听器时会发生同样的事情,您可以通过使用匿名箭头函数来解决它,这不是可管道运算符的选项:document.addEventListener('click', (event) => this.upsertEvent(event));
更深入的测试类:
如果你有这个课程:
class TestClass {
readonly attributeMethod = () => {
this.executeThis()
};
functionMethod() {
this.executeThis();
}
executeThis() {
console.log('hi');
}
constructor() {
document.addEventListener('click', this.functionMethod);
document.addEventListener('click', this.attributeMethod);
}
}
这将以角度转换为 ES5(不幸的是),这将导致:
"use strict";
var TestClass = /** @class */ (function () {
function TestClass() {
var _this = this;
this.attributeMethod = function () {
_this.executeThis();
};
document.addEventListener('click', this.functionMethod);
document.addEventListener('click', this.attributeMethod);
}
TestClass.prototype.functionMethod = function () {
this.executeThis();
};
TestClass.prototype.executeThis = function () {
console.log('hi');
};
return TestClass;
}());
如您所见,functionMethod
gets 放置在构造函数中,prototype
并且attributeMethod
is 位于TestClass
构造函数中。但是,只有可以通过使用attributeMethod
来访问this
类的_this = this
。
因此,当您将functionMethod
引用作为回调方法传递时,该方法将在实际执行该方法的上下文中调用。对 的引用也会发生同样的事情attributeMethod
,不同之处在于attributeMethod
在_this = this
其范围内。
推荐阅读
- reactjs - 当对象数组更改 *hooks* 时,useState 不会导致重新渲染
- huawei-mobile-services - 如何在 Harmony OS 的 TextField 中设置文本的颜色?
- android - 在 EnryptedSharedPreferences 中保存 CharArray
- android - Ionic/Angular + Firebase 与 Android 设备上的模拟器 = auth/network-request-failed
- visual-studio-code - Blazor WASM 独立调试停止工作
- javascript - 根据您对 Discord.js 做出反应的表情符号做一些事情
- android - 在预构建事件中设置 Visual Studio 中的 BuildAction
- python - Python 无法从 API 响应中删除文本
- java - 部署到 jboss EAP 7.1 时,此 URL 不支持 HTTP Post 方法
- bluetooth - 从 BLE 设备接收数据到树莓派 Pi3