Тъй като хората често се интересуват от Typescript и RxJs версията на моето приложение Elm (целият код от моя разговор за FullStack 2016 Haskell/Elm, вижте тази публикация за ресурси), изглежда полезно да напиша нещо за това къде да намеря този код и да добавя малко коментира целта си в беседата. Имайте предвид, че това е кратко ръководство за някои ключови моменти от кода, а не пълно обяснение.

Преглед на кода
Най-бързият начин да видите Typescript и RxJs кода е да видите източника в онлайн приложението с Chrome devTools (или предпочитания от вас браузър). Въпреки че Typescript работи като транспилиран код, магията на изходните карти означава, че браузърът с радост показва .ts файловете и поддържа точки на прекъсване и отстраняване на грешки с тях.

Клонирайте кода
Репото за кода е тук: https://github.com/jkbits1/HaskellElmTalk/tree/master/rxjs/src

Подходящи файлове и коментари — Typescript
От трите .ts файла само два са пряко приложими тук. Основното тяло на приложението (app.ts) използва модул, дефиниран в wheelCalcs.ts. Този модул съдържа типовете плюс свързани функции на алгоритъма. Функциите са дефинирани и експортирани в клас Calcs1. Еквивалентите на типовете Elm са дефинирани директно над този клас.

Съответни файлове и коментари — RxJs
Кодът Rx е в app.ts. Angular2 се променяше преди пускането и предишното използване на EventEmitter в това приложение за реагиране на входни промени вече е отхвърлено. Тук е заменен от RxSubject, който работи като директна замяна. Полезно е, че RxSubject има метода asObservable(), така че абонатите виждат само наблюдаема, а не самата тема.

RxSubject е полезен, когато искаме обект, който като форма на прокси може да наблюдава самите данни и да бъде абониран от един или повече наблюдатели. Един от обектите тук е BehaviorSubject, който предоставя първоначална стойност на абонатите. От гледна точка на Rx, това прави BehaviorSubject „горещ“ наблюдаем, а останалите „студени“. Първоначалната стойност задейства първото използване на алгоритъма и така показва първоначалните резултати.

Алтернативен подход за използване на RxSubject е да импортирате ReactiveFormsModule на Angular2 и да приложите директивата formControl към конкретни полета. След това тези полета стават директно наблюдаеми. Кодът за абониране е един и същ и за двата подхода.

Нашият абонаментен код е доста ясен. Ние извършваме стандартна защита от рикошет и реагираме само на действителни промени във входа. Сега обаче, когато имаме нашите данни като Rx потоци, би било много лесно да обединим и филтрираме данни от полета или да направим промени според стойностите на множество полета и т.н. Кодът ще остане еднакво декларативен.

input
.debounceTime(50)
.distinctUntilChanged()
.subscribe(
   this.updateModel(this, results, wheelPos),
…
);

updateModel() е еквивалентът на тази функция в приложението Elm. Той получава променения вход и преизчислява алгоритъма, което води до актуализиране на изгледа/ПИ. По този начин приложението следва еднопосочния модел на приложението Elm и като цяло поведението му е дефинирано в декларативен стил.

Еквивалентен код на приложението Elm
За да сравните приложението TS/Rx с приложението Elm (също изградено като модул и основно приложение), ето репо връзките: puzzle2-ui .elm, PuzzleModule.elm

Кодът wheelCalcs.ts по-горе е преобразуване на Elm PuzzleModule. Можете да видите онлайн приложението Elm (но няма картографиране на източник за Elm). Щракнете върху бутоните за завъртане, за да експериментирате с колелото на пъзела D3 и забележете как полетата за въвеждане се настройват автоматично. Присъщият еднопосочен стил на Elm улеснява работата на полетата за въвеждане, информационните елементи и т.н. в хармония.

Мисли за Rx в сравнение с Elm
Наистина харесвам силата и изразителността на Rx. Той позволява декларативно програмиране за широк набор от езици и среди, от които виждаме само малък вкус в този пример. Elm определено показа, че създава устойчиви приложения за браузър, които работят според плана, и това не е малко! Въпреки това, докато Elm 0.17 направи езика по-достъпен, той се отдалечи от началото на FRP. Това ме накара да се чудя колко лесно остава изграждането на различни форми на функционалност в стил Rx в Elm. В бъдеще може би ще трябва да взема решение дали проектите са най-подходящи за едната или другата от технологиите, а не и за двете. Планирам да направя някои тестове и може би някой път ще напиша публикация за това.

Надяваме се, че това ви е дало кратка представа за предимствата на TS, Rx и еднопосочния подход и как може да се свърже с вашите собствени проекти. Както и преди, обратната връзка е добре дошла.