#javascript #typescript #typescript-decorator
#язык JavaScript #машинописный текст #машинописный текст-декоратор
Вопрос:
Недавно я экспериментировал с оформителями машинописного текста, чтобы попытаться решить «проблему», которая есть у меня в приложении. Я использую мост JS для передачи кода TS как на Android, так и на iOS, и на данный момент мы объявляем такие функции:
index.js
import foo from './bar' global.App = function() { this.foo = foo; };
Вышесказанное сделает foo
функцию доступной на родной стороне моста
Я хотел написать декоратор для применения к этому foo
методу, который бы «зарегистрировался» сам по global.App
себе, но я не справился с этой задачей.
Вот декоратор, который работает:
export const Task = (target, propertyKey, descriptor) =gt; { let originalMethod = descriptor.value; descriptor.value = (...args) =gt; originalMethod.apply(target, args); if (!global.App) { global.App = function () { this.foo = descriptor.value; }; } return descriptor; }
Как я могу добавить другой метод к этой global.App
функции?
Комментарии:
1. Ваш код устанавливает
global.App
значение afunction
, но затем вы просто пытаетесь установить его значение как простое значение. Непонятно, чего вы пытаетесь достичь.2. Всякий раз, когда мы устанавливаем свойство для этой
global.App
функции, это свойство становится доступным на родной стороне через мост, и, таким образом, мы можем вызвать метод, который мы установили для этого свойства3.Вероятно, в вашем мостике есть обычное поведение, которое вызывает
global.App
. Как указано в комментарии Пойнти, в одном случае вы задаете его как функцию, в другом-как уже существующий объект. Также обратите внимание, что вы можете быть введены в заблуждениеthis
.4. В этом контексте это относится к внутренней функции, которую я назначаю
global.App
, верно? Как я могу добавить еще одно свойство вglobal.App
?
Ответ №1:
Во-первых, foo
метод добавляется только один раз, потому что при первом вызове декоратора global.App
определяется и ветвь, в которую добавляется foo
global.App
, никогда не вводится повторно.
Во-вторых, global.App
и foo
будет перезаписываться каждый раз и не поддерживаться путем повторных вызовов декоратору.
Добавление другой ветви, которая обрабатывает добавление метода после первого вызова и динамически присваивает имя метода , которое, как я полагаю, присваивается декоратору propertyKey
, позволит добавить несколько методов.
export const Task = (target, propertyKey, descriptor) =gt; { let originalMethod = descriptor.value; descriptor.value = (...args) =gt; originalMethod.apply(target, args); if (!global.App) { global.App = function () { this[propertyKey] = descriptor.value; }; } else { global.App[propertyKey] = descriptor.value; } return descriptor; }
Что — то вроде этого может сработать.
Комментарии:
1. Не сработало, глобальное. Приложение не определено после каждого шага.. Все еще пытаюсь понять, почему … в основном я поставил консоль. регистрируйтесь после каждого назначения, и это приведет к неопределенному
2. Хорошо, возможно, выделите раздел назначения, чтобы убедиться, что он определен.
Ответ №2:
Побродив так некоторое время, я нашел обходной путь для этого… возможно, мне не хватает знаний TS/JS, чтобы точно знать, что я хотел здесь сделать, но в любом случае мое решение состояло в том, чтобы зарегистрировать каждую задачу, а затем index.js
я получаю эти задачи и регистрирую их в global.App
функции.
Что — то вроде этого
задача.ts
export const TaskRegistry = {}; export const Task = (target, propertyKey, descriptor) =gt; { const originalMethod = descriptor.value; descriptor.value = (...args) =gt; originalMethod.apply(target, args); TaskRegistry[propertyKey] = descriptor.value; return descriptor; };
index.js
// eslint-disable-next-line func-names global.App = function () { // eslint-disable-next-line consistent-this const self = this; Object.keys(TaskRegistry).forEach((key) =gt; { self[key] = TaskRegistry[key]; }); }