Angular 为什么这些管道中的一个正确引用了“this”,而另一个没有?

Angular 为什么这些管道中的一个正确引用了“this”,而另一个没有?,angular,typescript,rxjs,Angular,Typescript,Rxjs,我正在构建一个可管道的操作符,但发现自己对这两种方法之间的区别一无所知。一个有效,另一个无效 export class CrudService { constructor(private datastore: DatastoreService, private http: HttpClient) { } // Making the operator an attribute on the object // instance allows `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
      })
    )
}
为什么this.datastore.validate_和_upsert在其中一个中工作,而在另一个中不工作

根据主持人的建议进行编辑
这个问题被重新表述,使其更加关注导致问题的原因。

这两个问题都是可通过管道传输的,但只有一个可以访问该类的上下文。我想你能猜出是哪一个。作为属性的一个。通过使用.bindthis可以解决此问题:

但就观点而言,我相信你问题中的属性方式更好

readonly upsertResponse = //...;
这样,您就不必担心这种上下文,而且很明显,该方法是一种实用方法

仅供参考,添加事件侦听器时也会发生同样的情况,您可以使用匿名箭头函数解决此问题,这不是可管道运算符的选项: 更深入的测试类:

如果你有这门课:

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被放置在原型上,attributeMethod位于TestClass构造函数中。但是,只有attributeMethod可以通过使用_this=this访问类的this


因此,当您将functionMethod引用作为回调方法传递时,将在实际执行该方法的上下文中调用该方法。attributeMethod的引用也会发生同样的情况,区别在于attributeMethod的作用域中有_this=this。

两者都是可管道的,但只有一个可以访问类的this上下文。我想你能猜出是哪一个。作为属性的一个。通过使用.bindthis可以解决此问题:

但就观点而言,我相信你问题中的属性方式更好

readonly upsertResponse = //...;
这样,您就不必担心这种上下文,而且很明显,该方法是一种实用方法

仅供参考,添加事件侦听器时也会发生同样的情况,您可以使用匿名箭头函数解决此问题,这不是可管道运算符的选项: 更深入的测试类:

如果你有这门课:

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被放置在原型上,attributeMethod位于TestClass构造函数中。但是,只有attributeMethod可以通过使用_this=this访问类的this


因此,当您将functionMethod引用作为回调方法传递时,将在实际执行该方法的上下文中调用该方法。attributeMethod的引用也会发生同样的情况,不同之处在于attributeMethod的作用域中有_this=this。

什么意思是阻止它可管道化?您是否收到错误?这是怎么一回事?我想这与访问正确的管道有关,根本不是管道,但是请给出一个答案。一旦你添加了任何错误,你就错了。什么是来源?如何使用upsertResponse?你到底是从哪里得到错误的?基本上,是的,这两个选项都应该起作用。但它们有不同的语义。所以认为它们可以互换是不正确的。@jornsharpe-你是对的,这是因为这个。当我删除依赖项时,它又起作用了。我没有发布更多的内容,因为我假设是构造导致了错误,结果是,正如你所建议的,引用了这个,你是什么意思,阻止它成为管道-你有错误吗?这是怎么一回事?我想这与访问正确的管道有关,根本不是管道,但是请给出一个答案。一旦你添加了任何错误,你就错了。什么是来源?如何使用upsertResponse?你到底是从哪里得到错误的?基本上,是的,这两个选项都应该起作用。但它们有不同的语义。所以认为它们可以互换是不正确的。@jornsharpe-你是对的,这是因为这个。当我删除依赖项时,它又起作用了。我没有发布更多的内容,因为我假设是这个构造是错误的,结果是,正如你所建议的,引用这个非常有用,谢谢Poul。我认为你是对的,我认为是这个导致了问题。但在这两次置换中到底发生了什么?我不太明白其中一个与另一个有什么不同-是一个返回函数,而另一个执行它?还是它们都返回相同的东西,只是其中一个捕获了这个值,而另一个没有?啊,我刚刚离开,了解发生了什么。这是因为,正如你所暗示的,胖箭头的工作方式是,它捕捉到了它的上下文价值。s
o第一个例子是使用胖箭头,而第二个不是@我已经详细阐述了一点,但你是对的:我对这个答案感到困惑。我的许多Angular服务中都有方法引用它,而不需要额外的.bind。这将很难理解,但我不想给出另一个答案:getProducts:Observable{返回This.http.getthis.productUrl.pipe tapdata=>console.log'All:'+JSON.stringifydata,catchErrorthis.handleError;}注意This.http。它很好用。这很有帮助,谢谢你。我认为你是对的,我认为是这个导致了问题。但在这两次置换中到底发生了什么?我不太明白其中一个与另一个有什么不同-是一个返回函数,而另一个执行它?还是它们都返回相同的东西,只是其中一个捕获了这个值,而另一个没有?啊,我刚刚离开,了解发生了什么。这是因为,正如你所暗示的,胖箭头的工作方式是,它捕捉到了它的上下文价值。所以第一个例子是使用胖箭头,而第二个不是@我已经详细阐述了一点,但你是对的:我对这个答案感到困惑。我的许多Angular服务中都有方法引用它,而不需要额外的.bind。这将很难理解,但我不想给出另一个答案:getProducts:Observable{返回This.http.getthis.productUrl.pipe tapdata=>console.log'All:'+JSON.stringifydata,catchErrorthis.handleError;}注意This.http。它很好用。
"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;
}());