All streams
Search
Write a publication
Pull to refresh
@Druuread⁠-⁠only

User

Send message
Раньше было модно писать статьи про монады. Сейчас стало модно писать статьи про редакс. А автор, видимо, решил хайпануть сразу с обеих тем?
> Черным ящиком могут выступать отдельно Model, View и Controller

Черным ящиком может выступать абсолютно все, что угодно, что данные откуда-то принимает, а потом куда-то передает. И потом описание этого чего-то может быть выражено в форме MVC.

> Controller именно представляет собой связующее звено между Model и View.

Нет, он связывает модель и вид с _устройствами ввода_, то есть входами, И это как раз основная отличающая фишка MVC. Из первой статьи по MVC:

> Controllers contain the interface between their associated models and views and the input devices
(keyboard, pointing device, time).

Ну и сам цикл работы:

> The standard interaction cycle in the Model-View-Controller metaphor, then, is that the user takes
some input action and the active controller notifies the model to change itself accordingly. The
model carries out the prescribed operations, possibly changing its state, and broadcasts to its
dependents (views and controllers) that it has changed, possibly telling them the nature of the
change. Views can then inquire of the model about its new state, and update their display if
necessary. Controllers may change their method of interaction depending on the new state of the
model.

Небольшое пояснение по последнему пункту — у одной модели может быть много пар контроллер+вид, и контроллер отвечает за оркестрацию пар. Например, у каждого меню — свой контроллер (с-но, когда меню открывается, надо деактивировать текущий контроллер, активировать контроллер меню и инициализировать его вид), у какого-нибудь скроллбара тоже свой контроллер — при наведении на скроллбар будет активирован контроллер скроллбара.

> все данные он получает от Controller, который и реализует основную логику приложения.

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

Ну в ангуляре это не так. В ангуляре ваш код инициализирует модуль, а рендер директив — побочный эффект. Все компоненты модуля рендерятся в местах, в которых расположены их селекторы (если для компоненты указан селектор) — это стандартное поведение компоненты. Для удобства при инициализации модуля это поведение блокируется для всех компонент, не указанных в рутах. У вас просто ментальная модель неправильная.
> Он просто рендерит компонент.

Так можно про что угодно сказать.
> Как рендерится Angular:

Этот код не эквивалентен коду на реакте. Эквивалентный код в ангуляре написать нельзя: ангуляр ничего не знает о дом и браузере. По-этому вы не можете ни создать дом-ноду, ни отрендерить ее в дом-ноду (при запуске, например, на декстопе, вне браузера, никакого дома может не быть, по--этому можно считать, что его по факту и нет).
> Вообще да, но в случае html ввод ведь поступает от тех же элементов dom, которые рисует представление.

Это не существенно, потому что:
1. внутренняя реализация дом-элементов вам не доступна
2. это поведение легко меняется тонкой прослойкой. Например, в реакте все эвенты сперва баблятся до рута и потом оттуда уже распределяются, куда нужно.

> Совсем по классике слишком сурово получится — не 70-е ведь.

Ну естественно, потому и создаются новые варианты архитектуры. В 70-е, чтобы понять, что кто-то кликнул по кнопке — надо было посмотреть, что там по координатам клика, выяснить, что кнопка, проверить, не перекрыта ли она какой-то открытой менюшкой и т.д.
Это и делал (в том числе) контроллер, сейчас контроллеры сверх-тонкие, (click)=«doSomething()» — вот весь ваш контроллер (обычно, но нередко бывают и более сложные кейзы, конечно же), и он сидит в разметке, которая, вроде как, вид. + появилась необходимость отделять стейт приложения (то самое, какой из табов открыт, какой чек нажат и т.д.) от данных — так и появился mvvm (контроллер с видом склеили, за моделью вида разместили модель данных).

Но выдумывать каких-то кадавров с контроллерами-прослойками — не нужно. Представьте себе классический веб — где у вас условный пхп выдает ответы в виде готовой страницы. У вас контроллер на клиенте (очевидно), модель — на беке, но и вид тоже на беке! Как бы вы сделали тут эту химероподобную MVC с контроллером-прослойкой? Отправили данные в модель на беке, оттуда отклик в контроллер на клиенте, который дергает вид с бека? Шиза же. А почему? Потому что поток данных вывернут. По какой такой причине у вас часть приложения, ответственная за обработку реакции пользователя, должна заниматься передачей данных от модели к виду? В этом ведь нету никакой логики.
> Стоит лишь осознать как писать правильный JSX и ещё пару правил и всё становится просто.

На ангуляре точно так же — разобрались с темплейтами и поехали. DI вас использовать никто не заставляет, особенности change detection'а проблем не доставят (если выполнять пару правил — точно тех же, к слову, как и в реакте :))
Что там еще подкапотного остается?
> Контроллер PenguinController занимается обработкой событий и служит посредником между представлением и моделью.

Контроллер не служит посредником. MVC — это модель черного ящика. Есть входы (действия пользователя), есть выходы (это реакция интерфейса), есть внутренняя логика (модель). Входы обрабатывает контроллер, выходы формирует вид. Информация от входов к выходам (от контроллера в вид) пробрасывается моделью. Вся идея MVC — в том, что обработчик входов полностью отделен от обработчика выходов. Если у вас контроллер и вид что-либо знают друг о друге — это нарушает основной принцип MVC. При чем модель в mvc — это не слой взаимодействия с бекендом, это, скорее, аналог view model из mvvm. Слой взаимодействия с бекендом находится за пределами MVC (можно сказать, что к нему должна быть стрелочка от модели). А то, что получилось у вас — это немного кривая mvvm.
> они сначала все хранили в сторе редакса

Но вы же значение там хранить не хотите. У вас очень странным образом нежелание хранить в сторе модель (то есть то, что там хранить нужно) соседствует с желанием хранить состояние интерфейса (то, что как раз не обязательно).

Кроме того, твиттер — плохой пример. У них очень простой интерфейс (по-этому вью-стейта там мало), и само состояние тоже маленькое, так что они себе могут позволить. Если внутренний стейт десятка сложных многошаговых форм перенести в редаксовский стор, то это будет уже сравнимо с текущим твиттеровским стейтом. А ведь это будет только небольшая часть приложения.

Но, конечно, если известно, что приложение не разрастется и не будет предоставлять каких-то сложных взаимодействий — такой подход тоже вполне приемлем.
> Я пока храню всё в сторе, игнорируя существование локального стейта компонентов

С-но вы же жаловались на то, что стор слишком толстый — вот я его и сделал еще тоньше :)
> и его надо и показать, и совершать какие-то бизнес-действия при достижении определенных значений

А вы можете в селекторах совершать какие-то действия? Наверное, нет.
Нетривиальную логику в селекторы просто by design засунуть не удастся, по-этому такой вариант и обсуждать особого смысла не имеет. Ну а что до тривиальной — понятно же, что все подобные утверждения вроде «так делать нельзя» не имеют статуса максимы и по факту обозначают что-то вроде «нельзя без явных причин». Если у вас есть явная причина засунуть что-то в селектор (вы четко видите, что это проще и удобнее других решений при прочих равных) — ну ради бога. Главное, чтобы задача была качественно решена.
> «где в React-приложении должен быть расположен код, отвечающий за бизнес-логику».

В модели (это стор, то есть редьюсеры). А вызываться — из контроллера. Контроллер в редаксе — это набор action creators, то есть больше бизнес-логику вызывать просто неоткуда, других точек входа не существует. А селекторы — это view, в них бизнес-логику нельзя располагать ни в коем случае, только логику вида. Иначе unidirectional data flow оказывается нарушен.

> Взглянем на action creator подробнее. Сначала ответим себе на вопрос: «у нас будет один action creator на все поля формы, или по отдельной функции на каждое из полей».

Один action сreator, который принимает a,b,c,d и возвращает type: «UPDATE_RESULT», payload: f(a,b,c,d). Сами a,b,c,d в сторе хранить не надо, т.к. они не входят в модель. Только результат.
Уменьшал экран, менял масштаб, возюкал мышкой — иногда бывает раз-два тикнет и все. Забагованный этот ваш фибер, короче.

ЗЫ: открыл десять вкладок одновременно — так же 60фпс на каждой, но ничего не тикает. Явно не в железе проблема.
> У вас слишком слабый комп

разогнанный i7 6700k
это что надо, чтобы оно тикало?
У меня под хромом в версии с файбером вообще цифры не тикают почему-то.
В вашем случае не надо делать 100500 кликов, надо сделать один (!) клик
> Так вот redux помогает это делать путем явного объявления, так что вам не придется искать где вы там на jquery сныкали setterы

Это вы о чем? Как раз на сеттер я прыгну по go to definnition, а вот сныканные экшоны мне придется искать.
> Например я могу добавить в интерфейс DATA_RECEIVED параметр «время отправки», а в редусере сравнивать время. Или сделать как в доке и не позволять отправить второй запрос пока идет первый.

Замечательно. Кто мешает все то же самое сделать с обычными функциональными вызовами? Это же достигается одной единственной функцией-оберткой.

> То у вас ужасные, мерзкие асинхронные мидлвари разворачивают поведение экшона на 180°, запускают ракету, то вдруг экшон который проходит через те же самые жуткие мидлвари ничем не отличается от сеттера

Все верно, мидлвари ничем не отличаются от сеттера — такие же грязные, такие же непредсказуемые в плане сайдэффектов. Я нигде себе не противоречил.
Так еще раз, если ему нельзя далеко скроллить, то зачем давать такую возможность? Уберите ее.
Одно дело, если бы оно работало — бог с ним, пусть, но оно ведь тормозит и виснет.
> Ага, только вот эти самые специальные усилия мне будет принимать намного легче, потому что я могу отловить эти самые DATA_RECEIVED, а не они тихо проапдейтятся где-то через сеттер или обсервабл.

А есть какие-то проблемы в том, чтобы залогировать точно так же обычные функции?

> А если для человека «Нет никакой разницы между вызовом экшона и вызовом функции, апдейтящей стор напрямую.»

Это не для меня ее нет, ее по факту нет. Вы никак не сможете по поведению определить, был ли вызван экшон, или стор обновили «напрямую».

Information

Rating
Does not participate
Registered
Activity