Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   React'а тред (https://javascript.ru/forum/offtopic/53890-react%27-tred.html)

Gozar 28.02.2015 19:58

Цитата:

Сообщение от l-liava-l
Википедия:
Цитата:
Шаблонизатор (в web) — это программное обеспечение, позволяющее использовать html-шаблоны для генерации конечных html-страниц.
Реакт предназначен именно для этого, а его возможности, недостатки и архитектура не имеют значения в данном случае.

Оно не конечный html страниц, оно виртуальный DOM, который рендерится в HTML. Оно не HTML, оно имеет XML ситнаксис, как минимум и оно имеет свой шаблонизатор.

Цитата:

Сообщение от l-liava-l
Ангуляр это целая система в которой тож есть свой шаблонизатор.

Это лицемерие. У реакта тоже есть шаблонизатор и называется он тадам JSX, а ещё есть архитектурное решение ака flux, а ещё есть аддоны, которые тоже часть системы. Не хочешь не подключай, ну дык я думаю в ангуляре также.

Будь здоров, кушай торт, он полезен :)

Gozar 07.03.2015 16:37

Есть две архитектуры flux(store, action, component, dispatcher). Одна зависима от другой. Это значит что пока 1 не обновиться, 2 не должен обновляться.
Как организовать внутри одного диспетчера я понимаю(ставим waitFor), а между двумя как построить взаимосвязь недогоняю.

Как организовать эту зависимость с диспетчерами?

melky 07.03.2015 18:11

Цитата:

Сообщение от Gozar (Сообщение 360043)
Есть две архитектуры flux(store, action, component, dispatcher). Одна зависима от другой. Это значит что пока 1 не обновиться, 2 не должен обновляться.
Как организовать внутри одного диспетчера я понимаю(ставим waitFor), а между двумя как построить взаимосвязь недогоняю.

Как организовать эту зависимость с диспетчерами?

Добро пожаловать на грабли событийного программирования! С моделями было проще, да?)

Flux должен быть один. Dispatcher - тоже. http://fluxxor.com/images/flux-complex.png

Хочу заметить, я перепробовал все способы и остановился на одном, как самом удобном. Он выделен красным. Почему он - расскажу в конце.

1. Асинхронные действия. Из action возвращаешь Promise. Когда он выполнится, выполняешь другое действие
2. waitFor. Это, можно сказать, сахар над Store.on('change'). Все просто - в хранилище A выполняешь waitFor('B', callback). Когда вызовится B.emit('change'), выполнится и переданный callback
3. Недокументированный API. Хранилища наследуются от EventEmitter. У него есть привычный всем метод once (колбек на один раз).
4. componentDidUpdate(prevProps, prevState) внутри Controller Component. Проверяем, изменились ли данные в новом состоянии. Если да - отсылаем action.

Теперь обо всём по порядку.

1. Асинхронные действия

добавляем в actions параметр callback, или возвращаем Promise.

Это идет в разрез с идеей Flux. Это не стоит использовать (имхо)

2. waitFor

waitFor мне неплохо вмазал (шо аж день не отпускало), так что, думаю, следует хорошо пояснить этот момент

Я использовал Fluxxor, так что его и буду описывать. Документация по Store.waitFor

Как вы видите, waitFor должен находиться внутри хранилища. Как тогда выполнить обновление с зависимостями?

A - master Store
B - slave Store


Сналача, регистрируем обработчик изменения через вызов нужного action (напр. Flux.actions.b.waitForAUpdate)
Далее, выполняем изменение хранилища A (напр. Flux.actions.a.setItem)

И приходим к проблеме. Вызов этого дела выглядит так:
Flux.actions.b.waitForAUpdate()
Flux.actions.a.setItem('yolo')


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

тут либо можно изгальнутся костылем, пустив обновление состояния A через таймаут:
Flux.actions.b.waitForAUpdate()
setTimeout( () => Flux.actions.a.setItem('yolo') )


либо вернуть из создателя действия (ActionCreator, лол) обещание, которое содержит в себе таймаут:
Flux.actions.b.waitForAUpdate().then( () =>
  Flux.actions.a.setItem('yolo')
)


Исходник для Flux.actions.b.waitForAUpdate получается таким:

Файл flux/actions/b.js:
export default {
  waitForAUpdate() {
    return Promise.delay().then(() => 
      this.dispatch('WAIT_FOR_A_STORE')
    )
  },
}

(Promise.delay - это нестандартный метод, из библиотеки bluebird)

Для сравнения, создатель действия без обещания - такой:
Файл flux/actions/b.js:
export default {
  waitForAUpdate() {
    this.dispatch('WAIT_FOR_A_STORE')
    // и чё, кода действие выполнится то?
  },
}


Если у вас крупное приложение, и действия отсылаются через таймауты, то у вас появятся проблемы, если вы будете использовать этот способ.

3. Недокументированный API.

У нас ведь Flux, так? значит, все действия и хранилища видны всему.

Вкратце - одноразово подписываемся на событие изменения, и из него уже дальше пляшем
Flux.stores('A').once('change', () => {
  // хранилище изменило состояние
  const AState = Flux.stores('A').getState()
  Flux.actions.b.doSimethingWith(AState)
})

Flux.actions.a.setItem('yolo')


Наверное, это дело лучше красиво спрятать в ActionCreator, обернув обещанием.

4. componentDidUpdate(prevProps, prevState)

Имхо, кажется костыльным и уродивым, но это похоже на самый хороший и добротный способ, с точки зрения асинхронной реактивности (имхо)

Состояние хранилищ передается controller component, который расфасовывает полученные данные вниз по дереву компонентов через свойства (props)

Fluxxor предоставляет сахарок для легкого подписывания на событие изменения хранилищ и перевод их состояний в состояние компонента.

componentDidUpdate, как вы знаете, вызывается после того, как у компонента сменились свойства или состояние. Ну и измениться они могут, в случае controller component, из-за смены состояния одного из прослушиваемых хранилищ

выглядит это так:

A - master Store
B - slave Store


Пусть компонент копирует состояния хранилищ в пространства имен :
// это - слушалка события 'change' у двух наших хранилищ
onSomeStoreChanged() {
  const A = Flux.stores('A').getState()
  const B = Flux.stores('B').getState()

  return { A, B }
}

// состояние хранилища A будет в this.state.A
// для B  - соотв.


отсылаем данные хранилищу A:
Flux.actions.A.setItem('yolo')


внутри CDU, если что-то изменилось, и это состояние хранилища А, то нужно обновить данные в В:
componentDidUpdate(prevProps, prevState) {
  if (this.state.A !== prevState.A) {
    Flux.actions.b.updateFromItem(this.state.A.item)
  }
}


ну, или можно использовать CWU (цепочка реакций должна пойти быстрее):
componentWillUpdate(nextProps, nextState) {
  if (this.state.A !== nextState.A) {
    Flux.actions.b.updateFromItem(nextState.A.item)
  }
}


А у нас цепочка зависимостей (A -> B -> C)? Тогда:
componentWillUpdate(nextProps, nextState) {
  if (this.state.A !== nextState.A) {
    Flux.actions.b.updateFromItem(nextState.A.item)
  }
  if (this.state.B !== nextState.B) {
    Flux.actions.c.updateFromItem(nextState.B.item)
  }
}


Как-то так ... в общем, у нас есть перенос логики обновления в компоненты-контроллеры, но для Flux - это нормально (вроде)

Почему лучше использовать CWU/CDU для цепочки событий? Все просто - действие (action), на момент выполнения этих методов, уже прошло круг от создателя действий до компонентов (напомню, только одно действие может обходить кружок в момент времени).

waitFor обеспечивает такой же функционал (вызывается, когда хранилище заявило об изменении состояния), но как вызвать действие (Action) внутри хранилища (Store)? МБ дело вкуса, но я лучше не буду пихать всякие actions.yolo() внутри чистенького Store.

Ну и еще - разделение логики обновления данных от самого обновления данных

И еще - абстрагирование от того, сколько действие выполняется. Получается действительно реактивная система обмена данными

Всё вышесказанное является огромнейшим ИМХО. Если есть предложения, буду рад их услышать.

melky 07.03.2015 18:45

Ещё пометочка, но отдельным сообщением.

1. Для сравнений типа this.state.B !== nextState.B нужно, чтобы данные не были мутабельными (иммутабельность, короче)

Это делается либо через _.cloneDeep, либо использованием билиотек, предоставляющих иммутабельные структуры данных

Можно и проверять на предмет изменения объекта через _.isEqual(this.state.B, nextState.B), но спор иммутабельность vs мутабельность - отдельная тема

2. Controller component - шаблон проектирования компонентов. Заключается в том, чтобы выделить 2 компонента, которые по одиночке используют один Store и поставить над ними родителя, который содержит в себе получение данных из Flux и её передачу по дереву компонентов с помощью props.

что-то типа такого (но тут не один Store, а два): http://2.bp.blogspot.com/-mSMHB7w43l...30.05%2BPM.png

count_control и sold_flag_control берется из Flux и передается компонентам через props с именами Sold flag и Count

melky 11.03.2015 11:57

React v0.13

Gozar 11.03.2015 14:24

Цитата:

Сообщение от melky
React v0.13

Не пинали бы меня со сроками запуска, начал бы переезд :)

Gozar 20.04.2015 23:03

Накой было резать html autocomplete?

nerv_ 01.05.2015 22:36

Поскольку ангуляр достал своим DI, тормозами и прочим, решил ознакомиться с реактом. Вчера посмотрел видео, сегодня почитал доку и написал первый пример на es6 + React.
//Test.jsx

class Test extends React.Component {

    render() {
        return (
            <h1>test</h1>
        );
    }

}

export default Test;

//client.js

import Test from './components/Test.jsx';

React.constructAndRenderComponent(
    Test,
    {},
    document.getElementById('container')
);

<!DOCTYPE html>
<html>
<head>
    <title>React Sandbox</title>
    <meta charset="utf-8">
    <script src="lib/react.js"></script>
</head>
<body>
    <div id="container"></div>
    <script src="dist/sandbox.js"></script>
</body>
</html>


результат https://yadi.sk/i/hrZgXP64gNiUf

С документацией по 0.13.2, конечно, беда.

Хочется, как в шаблонизаторе лепить ифы и фор_ичи, но нельзя :-E
Как же быть?
Смотрел в сторону react-templates, но не уверен.

Цитата:

Сообщение от l-liava-l
Ангуляр это целая система в которой тож есть свой шаблонизатор.

спрашивается, на кой такая система сдалась:
1. DI ангуляра не нужен, т.к. есть es6 модули
2. утилиты (forEach, isObject, etc) мне тоже не сдались, у меня свои
3. транспорт ангуляра (ajax) не требуется, у меня свой
Т.о., если модели у меня свои, утилиты свои, свой транспорт, но ангуляр заставляет меня юзать его собственные и при этом тормозит... не хорошо это :)
Да, с ним можно писать меньше кода. Декларативность нравится, но стоит ли оно того?
По большому счету, теперь мне нужна только вьюха.

Gozar 01.05.2015 23:19

Цитата:

Сообщение от nerv_
С документацией по 0.13.2, конечно, беда.

Там минимальные отличия от 0.12. Читай 0.12, отличия сами дойдут.

Цитата:

Сообщение от nerv_
посмотрел видео

Это видео, ещё та жесть. Смотри видео вконтактике в группе https://vk.com/reactjs и на eggheads


Цитата:

Сообщение от nerv_
Хочется, как в шаблонизаторе лепить ифы и фор_ичи, но нельзя
Как же быть?

Почему нельзя? Ещё как можно и нужно :)
Там сборка идет в рендере перед return

render: function () {
        var i = 0;
        var imgs = this.props.list.length == 0 ? '' : this.props.list.map(function(item){

                return <Photos
                            src={item.img}
                            title={item.name}
                            key={'photo-' + (i++)}
                        />;
            });
	    return (
            <div className="imgs">
            {imgs}
            </div>
	    );
}

Gozar 01.05.2015 23:21

Причем <Photos может состоять ещё из десятка компонентов или из одного <img>, это реально круто, наследование в html :)

Safort 01.05.2015 23:36

Gozar,
чуть более кошеrный вариант)

render() {
  let imgs = this.props.list.length == 0 ? '' : this.props.list.map(function(item, i) {
    return <Photos
                src={item.img}
                title={item.name}
                key={`photo-${i}`}
            />;
  });
  return (
    <div className="imgs">
    {imgs}
    </div>
  );
}

Gozar 02.05.2015 00:01

:)

nerv_ 02.05.2015 00:56

Цитата:

Сообщение от Safort
чуть более кошеrный вариант)

это все тихий ужас

Как вы опишите такую html структуру?

Гляжу, есть вкусности для coffee-script. Хочется чего-нибудь подобного.

UIjs 02.05.2015 01:05

блин ну и жестя, как вообще на нем писать??? О_О это ж слишком низкий уровень, как синхронить с моделями? как хранить данные? он же слишком низкоуровневый мать его, поверх него надо что то писать получается и уже на нем делать сайт?

Safort 02.05.2015 01:21

nerv_,
Цитата:

это все тихий ужас
UIjs,
Цитата:

блин ну и жестя, как вообще на нем писать???
Мелкого на вас нет!

UIjs,
Цитата:

О_О это ж слишком низкий уровень, как синхронить с моделями? как хранить данные? он же слишком низкоуровневый мать его, поверх него надо что то писать получается и уже на нем делать сайт?
Как-то так http://habrahabr.ru/post/249279/

Safort 02.05.2015 01:25

Gozar,
можешь рассказать, как у тебя устроено общение с сервером? Я сейчас Flux пытаюсь осилить и встал перед дилеммой - какая часть системы и когда начинает запрашивать исходные данные с сервера?

UIjs 02.05.2015 01:32

я посмотрел видео разные щас и так и не понял чем он лучше юишки моей... (
обьясните в чем прорыв? у меня можно написать ui-scrollbar в атрибуте, и создастся кастомный красивый скроллбар. можно так в реакте сделать?

nerv_ 02.05.2015 01:33

Цитата:

Сообщение от Safort
Мелкого на вас нет!

:)

похоже, альтернативы jade-react нет
ппц) Для того, чтобы писать шаблоны для реакта, придется писать их на jade (судя по всему).

или юзать react-templates
вроде симпатичная штука

Цитата:

Сообщение от UIjs
можно так в реакте сделать?

можно

Цитата:

Сообщение от UIjs
обьясните в чем прорыв?

кажись, только в скорости рендеринга, ибо это вьюха

Safort, хочешь сказать, ты шаблоны руками пишешь, без движков?) Это же ад)

Safort 02.05.2015 01:35

UIjs,
а я посмотрел твоё видео о твоей юишке и тоже ничего не понял :(

UIjs 02.05.2015 01:36

Цитата:

Сообщение от nerv_
только в скорости рендеринга

у меня тоже ассинхронка например

Цитата:

Сообщение от Safort
а я посмотрел твоё видео о твоей юишке и тоже ничего не понял

ты не смотрел видео о юишке, ты смотрел тока видео где я котику обьясняю зачем наследование нужно)

Safort 02.05.2015 01:37

nerv_,
Цитата:

ппц) Для того, чтобы писать шаблоны для реакта, придется писать их на jade (судя по всему).
Так Кобеззза же обещал поддержку реакта в новом SS, так что не стоит расстраиваться)

nerv_ 02.05.2015 01:37

Цитата:

Сообщение от UIjs
ты смотрел тока видео где я котику обьясняю зачем наследование нужно)

как же я пропустил такое :lol:

Safort 02.05.2015 01:40

UIjs,
Цитата:

у меня тоже ассинхронка например
А у тебя можно хранить состояние приложения в обычных объектах/массивах JS и чтобы после изменения этого состояния, всё само перерисовывалось как надо?)

nerv_ 02.05.2015 01:43

Цитата:

Сообщение от Safort
А у тебя можно хранить состояние приложения в обычных объектах/массивах JS и чтобы после изменения этого состояния, всё само перерисовывалось как надо?)

конечно, если он делал клон ангуляра

---

В целом, я посмотрел/почитал про реакт, и оказалось что, не только я юзаю по всюду методы getState()/setState(), реакт тоже ими оперирует (понятиями состояния приложения). Единственное что, вводится еще термин иммутабельность данных (в рамках реакта).

UIjs 02.05.2015 01:53

Цитата:

Сообщение от Safort
А у тебя можно хранить состояние приложения в обычных объектах/массивах JS и чтобы после изменения этого состояния, всё само перерисовывалось как надо?)

так так и есть)) более того, запрещено изменять разметку НЕ через состояние яваскрипт обьектов)

Цитата:

Сообщение от nerv_
клон ангуляра

с блекджеком и шлюхами, попрошу заметить. и напомню что у меня вообще всего 2 сущности, компонент (это какой то либо атрибут либо элемент созданый нами) и контроллер (это яваскрипт синглтон который виден везде и в котором храниится состояние). и все. создаем кастомные элементы да атрибуты, пишем контроллеры в которых храним данные и логику, и набираем из этого сайт прямо в index.html как из кубиков лего.

UIjs 02.05.2015 02:12

Цитата:

Сообщение от nerv_
клон ангуляра

и вообще-то я делал клон ангуляра до того как узнал про ангуляр) эт мне котик подсказал что мол скобчки на ангуляр похожи, я и решил прогуглиться

kobezzza 02.05.2015 09:04

Цитата:

Сообщение от Safort (Сообщение 369053)
nerv_,

Так Кобеззза же обещал поддержку реакта в новом SS, так что не стоит расстраиваться)

Угу, все будет.

Erolast 02.05.2015 10:51

Цитата:

чуть более кошеrный вариант)
Можно еще проще:
class Component extends React.Component {
    render() {
        let images = this.props.list.map(({img, name}, i) => (
            <Photos
                src={img}
                title={name}
                key={i}
            />
        ));
        
        return (
            <div className="images">
                {images}
            </div>
        );
    }
}


Цитата:

Как вы опишите такую html структуру?
Просто не надо все в один компонент пихать.

Цитата:

какая часть системы и когда начинает запрашивать исходные данные с сервера?
Action.

Цитата:

у меня тоже ассинхронка например
При чем тут асинхронность? Реакт, в первую очередь, быстрый за счет того, что работает в виртуальном DOM, а к реальному применяется только дельта.

UIjs 02.05.2015 11:08

Erolast, вот покажите например как в реакте сделать рекурсивное древо файловой системы например? а я покажу как на юишке)

Gozar 02.05.2015 11:19

Цитата:

Сообщение от Safort
как у тебя устроено общение с сервером?

Обычно ajax в componentDidMount.

Нужно чётко понимать что такое жизненный цикл.
http://tftf.ru/stati/javascript/reac...and_lifecycle/

А ещё нужно знать что можно вешать прослушку на изменение хранилища:
componentDidUpdate: function() {
        CommentsStore.addChangeListener(this._actionState);
    },

При изменении CommentsStore выполняем свою функцию this._actionState, которая обновляет комменты или что-то ещё делает...


Цитата:

Сообщение от nerv_
похоже, альтернативы jade-react нет
ппц) Для того, чтобы писать шаблоны для реакта, придется писать их на jade (судя по всему).

Я пишу спокойно на jsx и мне очень нравится.

Разбивать на компоненты. В компонентах могут быть свои обработчики(модульность!).

Цитата:

Сообщение от nerv_
иммутабельность данных

Можно поподробней, что там про иммутабельность?

Gozar 02.05.2015 11:23

Хочу попробовать http://fluxxor.com/ в нём сахара больше. В чистом React сахара маловато и flux тяжело даётся.

nerv_ 02.05.2015 12:26

Цитата:

Сообщение от Erolast
Можно еще проще

а вот ни разу не проще

Пример "рутового" шаблона простого приложения на ангуляре. Разумеется, внутри него есть другие компоненты.
Просто верстать, просто читать, просто поддерживать. Аналогичного хочется и от реакта.
<body>
    <div class="page">
        <div ng-app="insider" class="insider">
            <div ng-controller="insider.DefaultController" ng-cloak="">
                <div ng-if="app.isReady">
                    <div class="insider__controls affix btn-group-vertical">
                        <div ng-repeat="config in app.tools track by config.id" ng-insider-node="config"></div>
                    </div>
                    <div class="insider__header">
                        <div class="container-fluid">
                            <div class="modes">
                                <div class="row">
                                    <div class="col-4">
                                        <h3>Mode</h3>
                                        <select ng-change="app.setModeById(app.model.modeId)" ng-model="app.model.modeId" ng-options="mode.id as mode.title for mode in app.dictionaries.modes" class="form-control"></select>
                                    </div>
                                    <div ng-show="app.isFilterMode()" class="col-4">
                                        <h3>Presets</h3>
                                        <select ng-change="app.setPresetById(app.model.presetId)" ng-model="app.model.presetId" ng-options="preset.id as preset.title for preset in app.presets" class="form-control"></select>
                                    </div>
                                    <div class="col-4">
                                        <h3>Chunk</h3>
                                        <select ng-change="app.searchAsync()" ng-model="app.pagination.itemsPerPage" ng-options="chunk.value as chunk.title for chunk in app.dictionaries.chunks" class="form-control"></select>
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-7">
                                    <div class="form-horizontal">
                                        <div class="form-group">
                                            <div class="col-2 control-label">List</div>
                                            <div class="col-10">
                                                <select ng-change="app.setModeById(app.model.modeId)" ng-model="app.model.modeId" ng-options="mode.id as mode.title for mode in app.dictionaries.modes" class="form-control"></select>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-5 text-right">
                                    Добро пожаловать, <a href="#">Админушка</a>
                                    <button class="btn btn-primary" style="margin-left: 15px;">Выход</button>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- ADDING DIALOG :: START -->
                    <div ng-insider-dialog-adding="app.dialogs.adding" insider="app"></div>
                    <!-- ADDING DIALOG :: END -->

                    <!-- EDITING DIALOG :: START -->
                    <div ng-insider-dialog-editing="app.dialogs.editing" insider="app"></div>
                    <!-- EDITING DIALOG :: END -->

                    <!-- EDITING MULTIPLE DIALOG :: START -->
                    <div ng-insider-dialog-editing-multiple="app.dialogs.editingMultiple" insider="app"></div>
                    <!-- EDITING MULTIPLE DIALOG :: END -->


                    <!-- TABLE :: START -->
                    <div>
                        <table class="table table-hover insider-table">
                            <thead>
                                <tr ng-if="app.isFilterMode()" class="active">
                                    <th>
                                        <div class="btn btn-default btn-checkbox">
                                            <label>
                                                <input ng-model="app.model.selectedAll" ng-change="app.toggleSelection()" type="checkbox">
                                            </label>
                                        </div>
                                    </th>
                                    <th ng-repeat="field in app.fields track by field.id">
                                        <label ng-bind-html-unsafe="field.title"></label>
                                        <div ng-repeat="config in field.filter track by config.id" ng-insider-node="config"></div>
                                    </th>
                                    <th></th>
                                </tr>
                            </thead>
                            <tbody ng-hide="app.isPending">
                                <tr ng-repeat="record in app.records.getArray() track by record.atomId">
                                    <td>
                                        <input type="checkbox" ng-model="record._isSelected" ng-change="app.setSelection(app.getSelection())"/>
                                    </td>
                                    <td ng-repeat="field in app.fields track by field.id">

                                        <div ng-switch="field.isEditable">
                                            <div ng-switch-when="true">
                                                <div ng-if="!app.isCellEditing(record.id, $index)">
                                                    <div ng-repeat="config in field.reading track by config.id" ng-insider-node="config"></div>
                                                </div>
                                                <div ng-if="app.isCellEditing(record.id, $index)">
                                                    <div ng-repeat="config in field.editing track by config.id" ng-insider-node="config"></div>
                                                </div>
                                                <div ng-show="app.isCellSaving(record.id, $index)">Saving...</div>
                                                <button ng-click="app.toggleCellEditing(record.id, $index)" type="button">Edit</button>
                                            </div>
                                            <div ng-switch-when="false">
                                                <div ng-repeat="config in field.reading track by config.id" ng-insider-node="config"></div>
                                            </div>
                                        </div>

                                    </td>
                                    <td>
                                        <button ng-click="app.toggleFavorite(record.id)" type="button" class="hidden-button">
                                            <span ng-show="app.isFavorite(record.id)" class="favorite glyphicon glyphicon-star"></span>
                                            <span ng-hide="app.isFavorite(record.id)" class="favorite glyphicon glyphicon-star-empty"></span>
                                        </button>
                                        <button ng-click="app.openEditingDialog(record.id)" type="button">Edit record</button>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <div ng-show="app.isPending">
                            <p>Loading&hellip;</p>
                        </div>
                    </div>
                    <!-- TABLE :: END -->

                    <div class="container-fluid text-right">
                        <!-- PAGINATION :: START -->
                        <div ng-insider-pagination="app.pagination"></div>
                        <!-- PAGINATION :: END -->
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>


Цитата:

Сообщение от Erolast
Просто не надо все в один компонент пихать.

большинство приложений описывается жирным рутовым шаблоном в который подключаются готовые (свои/чужие) компоненты

Цитата:

Сообщение от Gozar
Я пишу спокойно на jsx и мне очень нравится.

я выше простой пример разметки привел. Думаю, на реакте его сложно будет описать на чистом jsx

Цитата:

Сообщение от Gozar
Можно поподробней, что там про иммутабельность?

насколько я понял и в двух словах, реакт требует копировать объекты/массивы для их быстрого и/или корректного сравнения (пока не понял что именно). Для этого есть либы, такие, как Immutable.js.

Gozar 02.05.2015 13:34

Цитата:

Сообщение от nerv_
Пример "рутового" шаблона простого приложения на ангуляре. Разумеется, внутри него есть другие компоненты.
Просто верстать, просто читать, просто поддерживать. Аналогичного хочется и от реакта.

Эта адская жесть из дивов и ng-чего-то там просто?

В реакте я работаю с компонентами, а не какими-то div-ами и шаблонами из каши html разметки. Ты же сам хвалил web-components и после этого кидаешь шаблон-кашу и говоришь что это хорошо. В то время как реакт гораздо ближе к web-components чем эта жесть.

Цитата:

Сообщение от nerv_
Аналогичного хочется и от реакта.

Ни в коем случае.

Ты похоже ещё не понял, что такое React и в чём его основная фишка.

Gozar 02.05.2015 13:39

Шаблон в реакт разбивается на компоненты, например:

Основной, верхнего уровня:
<TodoApp>
  <Header>
    <TodoTextInput />

    <MainSection>
      <ul>
        <TodoItem />
      </ul>
    </MainSection>

</TodoApp>


Далее делим на:
<MainSection>
      <ul>
        <TodoItem />
      </ul>
    </MainSection>


И только на самом примитивном уровне будет
<div className="blabla">{this.props.name}</div>


Думай компонентами, а не шаблонами!

Gozar 02.05.2015 13:43

Цитата:

Сообщение от nerv_
Думаю, на реакте его сложно будет описать на чистом jsx

Нет ничего проще. Разбиваем на части и жирный шаблон становиться меленькими, аккуратненькими компонентами.

UIjs 02.05.2015 13:51

Цитата:

Сообщение от Gozar
Эта адская жесть из дивов и ng-чего-то там просто?

тоже бесило это в ангуляр по этому я придумал неймспейсы, типа css- со стилями работают, ui- заменяется на какую то разметку, кастомный компонент типа, data- для работы с данными и.т.п.

nerv_ 02.05.2015 13:56

Цитата:

Сообщение от UIjs
тоже бесило это в ангуляр по этому я придумал неймспейсы, типа css- со стилями работают, ui- заменяется на какую то разметку, кастомный компонент типа, data- для работы с данными и.т.п.

покажи разметку

Цитата:

Сообщение от Gozar
Нет ничего проще. Разбиваем на части и жирный шаблон становиться меленькими, аккуратненькими компонентами.

Цитата:

Сообщение от nerv_
Разумеется, внутри него есть другие компоненты

уже разбит :)

UIjs 02.05.2015 13:57

nerv_,
Цитата:

Сообщение от Gozar
В реакте я работаю с компонентами

вообще-то в ангуляр так же, описываются компоненты и их шаблоны, и потом из них сайт набирается как из лего. всего 2 уровня, проэктный и базовй. как в MCSS


UIjs 02.05.2015 14:05

а вот результат https://www.youtube.com/watch?v=-TuhDVsoKYE

Gozar 02.05.2015 14:12

Цитата:

Сообщение от nerv_
уже разбит

Ну, что сказать, значит в ангуляр говно шаблонизатор, раз эта каша называется разбит.

Цитата:

Сообщение от Gozar
Основной, верхнего уровня:

Вот это значит разбит. А у тебя просто каша из html.

JSX - это по сути JS+XML, поэтому и более абстрактен и компоненты там в "html" выглядят как компоненты, а не как div-ы на которые сверху навешана гора атрибутов(Я ещё в fj понял, что получается каша если идти дорогой атрибутов, поэтому и свернул работы.).


Часовой пояс GMT +3, время: 09:36.