Pull to refresh

Comments 32

Немного оффтопа: пример с осциллографом улыбнул;)
Доводилось писать аналог. Пример почти «из жизни» :)
Спасибо.

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

Страница та выпадала в гугле по какому-то жутко умному запросу про MVC и не могла быть найдена просто так — просто была мусором в сети с кучей комментариев в стиле «хватит агрить парень, мир какой он есть!»

А сейчас вот, куча фамилий, сотни диаграм, на выходе вывод — ребята, вы неправильно понимаете MVC. Пора прекратить класть файлики в папки views, а нужно просто писать модули, которые имеют самостоятельный html/js, ну то есть вас пару лет за нос водили, теперь идем в другую сторону.

Радость то! Пришло таки :)

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

Может я конечно пол-статьи не понял, я такой паренек, который значит «увлекается в свободное время», а на работе умничать времени нету. Любопытно взглянуть на простейший пример нотации такого приложения, в котором логика контроллера внешнего модуля отвечающего за layout (имеющего вещи которые нужно сделать при инициализации) — не связана с модулем какой-нибудь драной кнопки или выпадающего меню, и как это сделать вне связей их друг с другом.

exports он разумеется есть, но чтобы добиться полной независимости, очень любопытно увидеть пример. на любом языке.
спасибо за «наводку» на пример «контроллер для «умного дома»»… Именна эта мысль меня и занимала последнее время — делать фасад как набор «команд». Интересно почитать как это реализовано у других. У меня тоже фасад довольно хорошо «разваливается» на независимые команды. Но чтобы понять почему у вас это не так… трех строчек что вы написали мало… нужно видеть весь ваш пример
Любопытно взглянуть на простейший пример нотации такого приложения, в котором логика контроллера внешнего модуля отвечающего за layout (имеющего вещи которые нужно сделать при инициализации) — не связана с модулем какой-нибудь драной кнопки или выпадающего меню, и как это сделать вне связей их друг с другом.

Я не очень понял, что вы имеете ввиду. Мы разрабатываем так, что есть корневой модуль, он внутри себя содержит "layout" модуль (или сразу от него наследуется), в который помещает модули экранов, которые может провязать друг с другом, через реактивные свойства. Например:


$my_app $mol_view
    sub /
        <= Layout $mol_book
            pages /
                <= Menu $my_task_menu
                    selected => task_selected
                <= Details $my_task_details
                    task <= task_selected -

Тут мы создаём корневой компонент, который внутрь себя помещает "книжную раскладку", в которую помещает две панели: меню со списком задач и подробности по выбранной задаче. При этом обе панели друг о друге не знают ничего, но корневой компонент берёт выбранную задачу из писка задач и биндит её на показываемую задачу в "подробностях".

Ну меня больше интересует сайт (или как сейчас модно — приложение), которое доступно в URL в интернете.

Если раскрывать вопрос по демонстрации: ну вот в качестве примера написать на этой позиции обычный такой landing-site с одной стороны на 2 страницы (чтобы была первая и вторая), с другой стороны с отправкой на email письма например, с третьей стороны с поддержкой «тем» и «языков»,
Ну то есть в каждой из сфер по два примера, и самое обидное — связать их так, чтобы была минимальная связность.

Обычно моя проблема в том, что модуль, который я внедряю в чей-то битрикс-говнокод так или иначе требует взаимодействия с самим битриксом. И начинаются связи и невозможность разделить его на маленькие модули — загоны в стиле — а где хранить ссылки на уже созданные объекты? если их хранить в каждом дочернем модуле, то это затраты памяти, делать их через статику — трудности в поддержке потом, когда видишь Class::method() и понимаешь что походу пора идти читать, что там в классе и когда писали.

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

Где баланс? Показал бы только пример кода.
Рассмотреть контроллер под конкретные случаи типа — контроллер шаблона. Это контроллер вообще? Нет наверное. С другой стороны ему нужно подготовить css/js под конкретный модуль, а родительскому — под себя и еще забрать у всех потомков и так рекурсией хрен знает сколько раз, чтобы была одна точка контроля на каждом уровне. Вот где самый расколбас.

Написать api на контроллерах, который возвращает json и принимает get/post/head быстро и легко — и поддерживать потом тоже легко. А вот когда начинается игра в «продвижение сайта» — начинается веселуха. Вот у тебя скрипты в модуле лежат — ты их слил в один красиво так, родительский модуль подхватил… и тут понимаешь, что jquery был в одном модуле и в другом — оппа уже dependency. А если депы, то значит контроль версий. А если контроль версий — то нужна шина — глобальный модуль, отвечающий за другие модули.

И поди его сделай фасадом, поди пойми, что в нем команда, а что просто объект, учитывая что весь код по сути состоит тоже ведь из команд. И вот эта двойственность слов — под словом команда можно понять это это и вон то — все губит. Вместо красивого кода получается опять связанный клубок ниток.

Опять же — примеры нужны, хоть какие-нибудь. Не картинки, а код — с определением в стиле «давайте представим что вот этот обьект — это команда».
Наверное самый разумный подход, это когда действительно есть обьект app хранящий экземпляры каждого модуля с возможностью доступа к ним в виде app.module.submodule.submodule.action();

И он же следит за dependency, и он же сжимает код и в общем-то молодец даже
http://patternlab.io предлагают думать о GUI в терминах Атом -> Молекула -> Организм -> Шаблон -> Страница:

БЭМ от яндекса давно разделило на блок-элемент-модификатор, при условии что одна DOM-нода может олицетворять несколько того и другого.

Это чертовски удобно, когда пишешь яваскрипт код под такую верстку, и в стилях вложенности по минимуму, и редактировать легко.

Молекулы? Что?

БЭМ от Яндекса — это костыль, который пытается бороться с отсутствием вложенности и namespace'ов в СSS. Туда же все эти OOCSS и прочие извращения.


Любить button button--state-danger или там .media__img--rev — это стокгольмский синдром.


То, что предлагает http://patternlab.io ортогонально BEM'у. Это подход к проектированию интерфейсов:


  • выделяем из интерфейса самые мелкие самодостаточные переиспользуемые компоненты: кнопки, поля ввода и т.п. Это «атомы»
  • Эти мелкие компоненты объединяются в более крупные блоки, которые тоже можно произвольно использовать заново: «поле поиска с кнопкой поиска» (состоящее из «поле ввода», «кнопка»), «меню» (состоящее из «кнопка», «список»(который состоит из «элемент для показа текста»)). Это «молекулы»
  • и так далее: «молекулы» компонуются в более сложные структуры. Эти более сложные структуры в еще более сложные и т.п.

Более подробно в Atomic Design: http://atomicdesign.bradfrost.com/table-of-contents/

UFO just landed and posted this here

Я так и не понял, почему вы противопоставляете "матрёшку" БЭМ-у. БЭМ — это один из способов реализовать ту самую "матрёшку", когда более крупные компоненты состоят из более мелких. И для этого вовсе не надо вводить странную номенклатуру "Атом -> Молекула -> Организм -> Шаблон -> Страница". Любой компонент ("блок" в терминологии БЭМ) может состоять из любых других компонент ("элемент" в терминологии БЭМ), которые также могут состоять из компонент и тд.


Все ваши претензии упираются в правила именования, которые можно выбирать любые. Мы, например, автоматически генерируем такие бэм-аттрибуты: my_sign_in_submit mol_view mol_button mol_button_type="major" — они позволяют точно понять где и зачем объявлен тот или иной стиль.


Например, следующее правило, добавляет всем нашим компонентам одни и те же стили по умолчанию, без влияния на не наши элементы:


[mol_view] {
    transition: all ease .1s;
}

А следующий задаёт особый размер нашей кнопке сабмита на форме входа:


[my_sign_in_submit] {
    font-size: 2rem;
}

Прелесть полного именования в самодокументированности, которую вы теряете при использовании коротких имён в изолированных контекстах. Изоляция контекстов позволяет не конфликтовать именам в рантайме. Но в мозгах программистов они всё-равно будут конфликтовать. Так что вам в любом случае придётся "восстанавливать контекст". С полными именами контекст у вас всегда перед глазами, а в стилях нет автогенерированной абракадабры, обеспечивающей уникальность имён.

И чего же сразу на помойке.
Если провести аналогию на жизнь — то каждый человек называет вещи своими именами отличными от других человеков (блоков в нашем случае).

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

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

block-block__element-element_modif, и все классы в таком виде.
Вложенность только там, где есть _modif, т.к. в пределах вариации дочерние элементы могут отличаться внешне.
Вроде все просто?

Поясните вашу точку зрения с бесконечным усложнением, потому что мне не понятна причина выбрасывать на помойку текущее решение.
UFO just landed and posted this here
Спасибо, но мне не удалось понять вашего объяснения, потому что я не увидел ни одной аналогии и живого примера. К тому же я обратил внимание, что вы не поставили никакой оценки моему высказыванию и просто его проигнорировали (я не про лайки, я про оценку наличия в нем смысла)

Я конечно ожидаю, что вы можете сейчас отреагировать не так как я ожидаю, но в этом случае сможем завершить дискуссию
UFO just landed and posted this here

Вы говорите о композиции компонент управляемой данными. Реализуется это достаточно не сложно. Но при чём тут БЭМ и вообще CSS?

UFO just landed and posted this here

Так работает, например, визуализатор маркдауна. В результате парсинга получается AST, по которому собирается дерево компонент.


Контент нод в структуре может быть любым.

И каждая нода — отдельный блок. Они же не зависимы, раз компонуются как угодно.

В прямом смысле слова достаточно сложно.
Дано — «разобранные» компоненты
Должны получить

Я может чего-то не понимаю, но вроде ничего сложного тут нет:
var data = [
 {"a":{"parent":"b"}},
 {"c":{"parent":"b"}},

 {"d":{"from":"a"}},
 {"d":{"from":"c"}}
];


var components = {};
var imports = {};

// prepare
for (var i in data) {
  var item = data[i];
  var componentName = Object.keys(item)[0];
  var itemData = item[componentName];

  if (itemData.parent != undefined) {
    parentComponentName = itemData.parent;

    components[componentName] =
      {parentName: parentComponentName, children: {}};

    components[parentComponentName] = {parentName: null, children: {}};
  }

  if (itemData.from != undefined) {
      var fromComponentName = itemData.from;
      imports[fromComponentName] = componentName;
  }
}

// make
for (var i in data) {
  var item = data[i];
  var componentName = Object.keys(item)[0];
  var itemData = item[componentName];

  if (itemData.parent != undefined) {
      parentComponentName = itemData.parent;
      components[parentComponentName].children[componentName] =
        imports[componentName];
  }
}

// clean
for (var i in components) {
    if (components[i].parentName != null) {
      delete components[i];
    } else {
      delete components[i].parentName;
    }
}

console.log(JSON.stringify(components, null, 2));

/*
{
  "b": {
    "children": {
      "a": "d",
      "c": "d"
    }
  }
}
*/
UFO just landed and posted this here
Будет аналогично, только появятся внутренние циклы и доступ по индексам, а не по свойствам. Произвольное имя задать вряд ли получится, так как обработка определяется его семантикой. Можно попробовать сделать одноименные функции и вызывать по названию.
UFO just landed and posted this here
Та я ж не доказываю, я пытаюсь вашу точку зрения понят, но я не вижу ничего кроме `Model Entities` и `Drupal`, которые тоже не вижу, потому что не знаю что это, и до ваших примеров, что это действительно решение многих проблем — даже знать не хочу что это.

Вы можете теперь сослаться на то, что я лентяй или как угодно поступить, но я правда ожидаю от вас примера из жизни как это работает, и почему это легче для каких задач. Пока вижу голые фразы, намеки на почитать — но зачем мне читать бескрайние берега? Разводил мало в жизни? Давайте уже работать, а не демонстрировать, если хотите программирование на новый уровень.
UFO just landed and posted this here

Мы похоже на разных языкх разговаривем.


Что такое "сборка компонент"? и зачем дизаинерам знать имя родительского? Что такое "цепочки"? что за "ключи" генерируются и зачем?

UFO just landed and posted this here

Понятней не стало :-) Что значит "собрать структуру по ключу", зачем её собирать и при чём тут компоненты?

UFO just landed and posted this here

Это вы описываете какое-то своё решение не понятно какой задачи. Если нужно "соединять независимые компоненты друг с другом", то это легко делается через биндинги. Пример, я приводил выше.

UFO just landed and posted this here

о «загрязнении» Модели настройками интерфейса

На "подумать" для желающих:

  • допустим у меня есть чекбокс и текстовое поле, которое должно быть доступно для редактирования (enabled) только если галочка стоит; а если она не стоит, то текстовое поле должно быть пустое. Так вот, где эта логика должна быть прописана, в M, V или C?

  • допустим, у меня одна и та же информация отображается одновременно и в таблице, и в списке; если в таблице выбрана какая-то строка - где должна информация об этом выделении храниться, в M, V или C?

Sign up to leave a comment.

Articles