Comments (14)
// Вариант первый, самый старый, появился когда в javascript ещё не было аксессоров.
// Наследоваться от EventEmitter в первом варианте не обязательно.
class Sstore extends EventEmitter {
constructor(s) {
super();
this.store = cellx(s);
}
}
const test = new Sstore(55);
// Подписка:
test.store.on('change', ()=>{\* *\});
// или
test.store.onChange(()=>{\* *\});
// Чтение:
test.store(); // 55
// Запись:
test.store(5);
// Вариант второй.
// В javascript появились аксессоры.
import { define } from 'cellx';
class Sstore2 extends EventEmitter {
constructor(s) {
super();
define(this, {
store: s
});
}
}
const test2 = new Sstore2(55);
// Подписка:
test2.on('change:store', ()=>{\* *\});
// Чтение:
test.store; // 55
// Запись:
test.store = 5;
// Вариант третий.
// В javascript появились декораторы через транспайлеры (babel, typescript).
import { Observable } from 'cellx-decorators';
class Sstore2 extends EventEmitter {
@Observable
store = null;
constructor(s) {
super();
this.store = s;
}
}
const test2 = new Sstore2(55);
// Подписка:
test2.on('change:store', ()=>{\* *\});
// Чтение:
test.store; // 55
// Запись:
test.store = 5;
from cellx.
Расскажу как это внутри устроено, может пригодится.
В основе лежит класс Cell. Всё остальное -- обёртки над ним. Первая обёртка -- функция cellx, возвращает рабочую функцию которой на свойство cell добавляется экземпляр класса Cell. Рабочая функция при вызове без аргументов прочитает значение из экземпляра Cell, а при вызове с аргументом запишет его в Cell. Так же у рабочей функции подменяется прототип в котором теперь добавлены некоторые методы. Все они просто проксируют вызовы на экземпляр Cell.
Вторая обёртка defineObservableProperty прячет экземпляр Cell в Map-e хранимом на объекте (на котором определяется реактивное свойство) по символу KEY_VALUE_CELLS. И создаёт на объекте getter и setter проксирующие чтение/запись на спрятанный Cell. В спрятанном Map-е в качестве ключа -- имя свойства, значение -- соответствующий свойству экземпляр Cell. В классе EventEmitter сделан костыль, который, видя в типе события двоеточие, тоже лезет в спрятанный Map для добавления обработчика к экземпляру Cell.
Третья обёртка в виде декораторов Observable и Computed так же как и вторая работает с тем же Map-ом, но getter и setter создаются теперь через декораторы сразу на прототипе класса, а не через вызов метода defineObservableProperty в конструкторе. Это немного выгоднее по памяти, тк. getter и setter теперь определены в прототипе для всех экземпляров, а не создаются новые для каждого.
from cellx.
Вариант с define согласен, работает.
Первый вариант конечно, в таком виде, сработает потому что мы обращаемся непосредственно к атрибуту класса обернутого в Cell который имеет возможность непосредственно подписаться на данную ячейку.
А вот последний вариант не сработает в таком виде, выдает ошибку указанную выше.
from cellx.
Поправьте в третьем варианте test
на test2
в последних двух строчках и всё заработает.
from cellx.
На ошибки в примере, приведенном Вами выше, там все понятно с названиями переменных. Конкретно данный пример выдает ошибку попробуйте у себя.
import {Observable} from 'cellx-decorators';
class Sstore extends EventEmitter {
@Observable store = null;
constructor(s) {
super();
this.store = s;
}
}
const ss = new Sstore(55);
ss.on('change:store', (evt) => {
console.log('ss', evt);
});
"cellx": "1.10.8",
"cellx-decorators": "1.6.2"
from cellx.
В typescript без проблем заработало. У вас babel?
from cellx.
да babel плюс зависимости:
// config-overrides.js
const {
addDecoratorsLegacy,
override,
disableEsLint,
addBabelPlugins
} = require("customize-cra");
module.exports = override(
disableEsLint(),
addDecoratorsLegacy(),
addBabelPlugins(
"@babel/plugin-proposal-export-default-from"
)
);
// package.json
"devDependencies": {
"@babel/plugin-proposal-decorators": "^7.10.1",
"@babel/plugin-proposal-export-default-from": "^7.10.1",
"customize-cra": "^1.0.0",
"react-app-rewired": "^2.1.6"
}
from cellx.
Ошибка в этой функции из node_modules/cellx/dist/EventEmitter.js
_on(type, listener, context) {
let index;
if (typeof type == 'string' && (index = type.indexOf(':')) != -1) {
let propName = type.slice(index + 1);
currentlySubscribing = true;
>>Здесь>> ((this[KEY_VALUE_CELLS] || (this[KEY_VALUE_CELLS] = new Map())).get(propName) || (this[propName], this[KEY_VALUE_CELLS]).get(propName)).on(type.slice(0, index), listener, context);
currentlySubscribing = false;
}
else {
let events = this._events.get(type);
let evt = { listener, context };
if (!events) {
this._events.set(type, evt);
}
else if (Array.isArray(events)) {
events.push(evt);
}
else {
this._events.set(type, [events, evt]);
}
}
}
from cellx.
При той же конфигурации babel на версии cellx 1.10.5 все работает.
from cellx.
Попробуйте обновить cellx-react до последней версии. Должно заработать. Если не заработает, то посмотрите настройки babel-я вот в этом проекте react-cellx-todo-app. Я обновил там всё до последних версий.
from cellx.
Выяснил в чем проблема была и есть:
После смены версии компилятора typescript с версии 3.8.* на 3.9*, он неправильно компилит работу с контекстом.
После того как перекомпилил исходник cellx на версии 3.8 все стало работать правильно с теми зависимостями babel что указывал выше.
С react-cellx-todo-app все работает и так, надо разбираться дальше какие плагины бабеля неправильно понимают скомпилированое typescript 3.9* версии.
from cellx.
Могу просто перекомпилить версией 3.8.*. Нужно?
А почему неправильно?
export class Cell extends EventEmitter {
}
Заменяет на:
let Cell = /** @class */ (() => {
class Cell extends EventEmitter {
}
return Cell;
})();
export { Cell };
Вроде всё корректно, хоть и непонятно зачем.
from cellx.
Извиняюсь, неправильно выразился.
В зависимости нужно добавить плагин:
@babel/helper-call-delegate
и все заработает.
Проблема решена.
from cellx.
За поправку cellx-react отдельное спасибо.
from cellx.
Related Issues (20)
- Guidance requested
- Untranslated part of README HOT 1
- Одно вычисление а не два HOT 2
- Please include Sodium FRP in your PERF
- Как сделать подписку с учётом будущих изменений? HOT 6
- Сломаны removeChangeListener и unsubscribe HOT 4
- dispose throws unexpectedly HOT 1
- why a varargs/overloaded API? HOT 2
- consider switching to Rollup HOT 5
- Good way to implement auto-run? HOT 3
- Error rethrowed only once HOT 12
- Зачем `let reactions = this._reactions;` HOT 1
- Ожидание корректного значения HOT 1
- Почему dep._addReaction после pull делает ячейку DIRTY? HOT 1
- _deactivate() не чистит this._dependencies HOT 5
- После fail executon всея ячейки дерева state ACTUAL HOT 4
- Async cell HOT 3
- value instanceof EventEmitter. Подписка в конструкторе HOT 1
- "effects" in cellx HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cellx.