Используйте декоратор свойства, чтобы инициировать класс - PullRequest
1 голос
/ 22 мая 2019

Я пытаюсь создать декоратор свойства в Angular 7, который запускает класс для переменной set

export class NewDataClass() {
   public readonly status = { loaded: false }
   public greet() {
      return 'hello';
   }
}

, и создать декоратор, который возвращает этот новый класс с некоторыми параметрами

export function NStatus() {
  return function(target: Object, key: string | symbol): any {

    return new NewDataClass();
  };
}

@Component({
  selector: 'app-new',
  templateUrl: './new.component.n.html',
  styleUrls: ['./new.component.n.scss']
})
export class NewComponent implements OnInit, OnDestroy {
  @NStatus() public status: NewDataClass;
}

При инициализации компонента значение status должно быть равно new NewDataClass.Помощь

1 Ответ

3 голосов
/ 22 мая 2019

Вы не можете сделать это напрямую от декоратора.Декоратор вызывается при создании класса (не при создании экземпляра), поэтому все, что мы можем сделать, это изменить сам класс в соответствии с нашими потребностями.

Один из вариантов - преобразовать поле в свойство и создать экземпляр значения в методе получения.:

function NStatus() {
    return function (target: Object, key: string, desc?: PropertyDescriptor): PropertyDescriptor {
        return {
            get: function (this: Record<string, NewDataClass>) {
                return this["_" + key] || (this["_" + key] = new NewDataClass())
            },
            set: function (this: Record<string, NewDataClass>, value: NewDataClass) {
                this["_" + key] = value
            }
        }
    }
}

class NewComponent {
    @NStatus() public status: NewDataClass;
}

console.log(new NewComponent().status);

Другой вариант, поскольку мы говорим об угловых компонентах, мы можем переопределить ngOnInit из декоратора и выполнить там инициализацию:

function NStatus() {
    return function <K extends PropertyKey>(target: { ngOnInit?: () => void  }, key: K): void {
        const originalNgOnInit = target.ngOnInit;
        target.ngOnInit = function (this: Record<K, NewDataClass>) {
            // Init the field
            this[key] = new NewDataClass;
            // Call original ngOnInit if any
            if(originalNgOnInit) originalNgOnInit.call(this);
        }
    }
}

class NewComponent {
    @NStatus() public status: NewDataClass;
    ngOnInit () {}
}

const c = new NewComponent()
c.ngOnInit();
console.log(c.status);

Перехват конструктора класса издескриптор свойства, к сожалению, невозможен.

...