Typescript Как вернуть ссылку на функцию класса из метода получения вложенных объектов - PullRequest
0 голосов
/ 14 сентября 2018

Я пишу класс обслуживания, который содержит набор служебных функций.Вместо того, чтобы выставлять все функции как открытые, функции объединяются в серию открытых объектов, которые предназначены для обеспечения логического потока для доступа к ним.Вот пример:

class MyUtilService {
    public exposedObject = {
        get prop1() {
            return this.utilFunction1;
        },
        get prop2() {
            return this.utilFunction2;
        }
    };

    private utilFunction1() {//...}
    private utilFunction2() {//...}
}

Проблема в том, что объект this в получателях ссылается на exposedObject НЕ класс (как и следовало ожидать).Цель состоит в том, чтобы получить доступ к этим функциям в другом месте приложения следующим образом:

myUtilService.exposedObject.prop1() // Want this to execute utilFunction1

Другое желание заключается в том, чтобы информация о наборе из utilFunction1 поддерживалась при использовании.Ранее я использовал .bind(this) вместо получателей, но это препятствовало передаче любой информации о наборе.То же самое происходит с Object.defineProperty.Любые мысли о том, как я мог бы заставить это работать?

Примечания: Использование TS 2.5.x и Angular 5.x

РЕДАКТИРОВАТЬ: IЯ добавляю некоторую дополнительную информацию, так как суть проблемы не ясна в моем первоначальном посте.Основная проблема возникает, когда одна из частных функций использует другую функцию из службы.Рассмотрим этот код:

class MyUtilClass {
    public exposedObject = {
        prop1: this.utilFunction1
    };

    private utilFunction1() {
        this.utilFunction2();
    }
    private utilFunction2() {//...}
}

// Want this to execute utilFunction1 which executes utilFunction2
someService.exposedObject.prop1()

utilFunction2 используется внутри utilFunction1, но когда вызывается myUtilClass.exposedObject.prop1(), this.utilFunction2 не определяется, поскольку контекст this получен от вызывающей стороны (опять же, как и ожидалось)).Это можно преодолеть с помощью prop1: this.utilFunction1.bind(this), но тогда вы потеряете информацию о наборе для функции.Это загадка.Вот почему я пошел по пути вложенных геттеров, но у него есть свои проблемы с контекстом this.

Ответы [ 3 ]

0 голосов
/ 14 сентября 2018

TypeScript - это настоящий JavaScript под капотом. Ваш класс преобразуется в функцию javascript перед выполнением. например, когда вы определяете функцию с помощью get или set ключевое слово, которое вы не используете ():

o = {
  get number() {return 5;},
  set number(i) {this.myNumber = i;}
}
result = o.number;
o.number = 10;

Каждый объект {} имеет собственный контекст this

Я даже не верил, что то, что вы ожидаете, возможно. Я немного поиграл с твоим классом. Я смог передать внешний контекст внутреннему объекту, но приватные методы все еще доступны как общедоступные. Похоже, что это верно для всех классов TypeScript, так же как и для js, все члены являются открытыми. Я новичок в TypeScript и просто хотел показать, насколько прототип (TS и JS) отличается от классического ООП

class MyUtilService {
  public exposedObject: Object;
  constructor() {

    class ExposedObject {
      constructor(private parent: MyUtilService) {}
      get prop1() {
          console.log(this);
          return this.parent.utilFunction1();
      }
      get prop2() {
          return;
      }
    }
    this.exposedObject = new ExposedObject(this);
  }


  private utilFunction1() { return 'uf'; }
  private utilFunction2() {}
}

const u = new MyUtilService();
const value = u.exposedObject.prop1;
console.log(value);
console.log(u.utilFunction1());
0 голосов
/ 14 сентября 2018

Хорошо, вот как я решил это. Используя тот же пример, что и раньше:

let _otherService: OtherService;

export class MyUtilClass {

    constructor(private otherService: OtherService) {
        _otherService = otherService;
    }

    public exposedObject = {
        prop1: utilFunction1
    };
}

function utilFunction1() {
    utilFunction2();
}
function utilFunction2() {
    _otherService.doSomething();
}

В итоге я определил вспомогательные функции вне основного класса. Тогда больше не было проблем с this. Функции могут использовать друг друга, и я мог бы даже предоставлять внедренные сервисы через конструктор, чтобы они могли ссылаться на них (возможно, так как сервис создается до того, как какая-либо из этих функций будет доступна). И информация о типе также наследуется через экспонированный объект. Спасибо всем за предложения!

0 голосов
/ 14 сентября 2018

Это должно работать для вас, учитывая то, что вы пытаетесь достичь.

class MyUtilService {
    public exposedObject = {
        prop1:this.prop1,
        prop2:this.prop2
    }
    private get prop1(){
        return this.utilFunction1();
    }
    private get prop2() {
        return this.utilFunction2();
    }

    private utilFunction1() {}
    private utilFunction2() {}
}

let utilityservice = new MyUtilService();
utilityservice.exposedObject.prop2;
...