bem / bem-xjst

bem-xjst (eXtensible JavaScript Templates): declarative template engine for the browser and server
https://bem.github.io/bem-xjst
Other
115 stars 47 forks source link

Keep `this.mods` when element in the block content #339

Closed miripiruni closed 8 years ago

miripiruni commented 8 years ago

https://goo.gl/ufn4Ya

cc @zxqfox @Yeti-or

miripiruni commented 8 years ago

@zxqfox @Yeti-or ребят, по поводу вашего вчерашнего вопроса. Сохранять модификаторы не надо. Это багоопасно и непредсказуемо. Тот факт, что в вашем примере два раза использовано одно и тоже имя b2 (сначала в подпредикате, а затем в достраивании контента) не даёт нам уверенности, что нужно сохранять модификаторы.

Представте себе обратную ситуацию:

block('b2').mod('m','v').content()({
    block: 'any-inner',
    content: {
      block: 'b2' // (1)
    }
});

Если сохранять модификаторы, то необходимо будет указать (1) mods: {}, что вообще неочевидно.

Не очевидно, потому что там явно указан блок без модификаторов. И если вы хотите чтобы произошло именно так, то придется делать дополнительное движение — указывать mods: {}. Более того, в данном примере произойдет рекурсия.

pvdz commented 8 years ago

@miripiruni wrong user

miripiruni commented 8 years ago

@qfox I'm sorry. ¯ \ (ツ) / ¯

qfox commented 8 years ago

Если сохранять модификаторы, то необходимо будет указать (1) mods: {}, что вообще неочевидно.

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

miripiruni commented 8 years ago

Почему нельзя сделать так, чтобы когда создается новый блок — модификаторы были новые, а когда элемент — то mods были от блока?

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

qfox commented 8 years ago

Давай еще раз пройдемся, может я чего-то не понимаю:

Это багоопасно и непредсказуемо.

Жить вообще опасно. От этого умирают. Фактуру давай, какие баги появятся, почему ты считаешь что они появятся. Мне в голову приходит обратная ситуация, когда мы пишем: block('b').mod('m', v').elem('e') в шаблоне, и они у нас перестают внезапно работать на сервисе, потому что элементу сделали wrap или replace: http://goo.gl/8OazIB

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

Представте себе обратную ситуацию:

Если сохранять модификаторы, то необходимо будет указать (1) mods: {}, что вообще неочевидно.

Почему ты думаешь, что я тебя прошу переносить модификаторы одного блока на другой блок, пусть и вложенный? Я, как раз, не ожидаю, что при вложенных блоках они как-то должны дружить модификаторами. Ситуация изначально была про элементы блока, которые теряют модификаторы блока, а твой пример работает правильно на мой взгляд, и про него речь даже не шла.

Предложение указывать явно mods: {} для блока в элементе это такой же костыль как и дублировать явно модификаторы блока на элементе, которым приходится сейчас пользоваться. В 99% случаев пользователь не должен хотеть этого делать — ему должно быть достаточно тех модификаторов блока, которые он указал на ноде самого блока в bemjson. Если у тебя есть другое мнение на сей счет — я хотел бы его выслушать.

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

Например, есть у нас {block: 'a', mods: {m: 'v'}, content: {elem: 'e'}}. Элемент e относится к блоку a, у которого есть модификаторы. Если я в нём явно напишу {block: 'a', elem: 'e'} он точно так же будет относится к блоку а, у которого есть модификаторы, потому что он в нём лежит. И если между ними будет что-то еще — блок a, к которому относится элемент, не должен терять модификаторы, иначе получается странная ситуация, отчасти противоречащая методологии в целом, потому что элементы не могут существовать без блоков.

По какой причине ты считаешь, что если я пишу там block явно, то я хочу, чтобы у блока пропали модификаторы? В 99% случаев я пишу block явно, чтобы элемент не уехал к другому блоку. Это случается по куче разных причин, в т.ч. и отчасти в связи с проблемами в самом bem-xjst: https://github.com/bem/bem-xjst/issues/193.

Исходя из всего вышесказанного, стоит задачу переоткрыть и осмыслить чего нам будет стоить починка. Или как?

P.s. Какой смысл у поля this.mods? Кажется, что если там что-то приватное, то его надо убрать, а если публичное — то должен быть какой-то вменяемый смысл. Я исхожу из того, что это модификаторы блока, к которому относится элемент. И в этом случае вложенность не играет никакой роли и никак не меняет ни связи элемента с блоком, ни модификаторов на самом блоке. Это значит, что там должны быть модификаторы блока, к которому относится элемент. А разрешать ли костыль в виде передачи поля mods в ноду элемента, или нет — на самом деле вопрос. Я бы в режиме разработчика, как минимум, ругался на такое, если в bemjson оно приезжает, потому что это показатель низкого качества кода шаблонов.

miripiruni commented 8 years ago

Тогда, похоже, вопрос сводится к нашему расхождению в нашем общем понимании наследования модификаторов в bemjson-е.

Я считаю, что если ты объявил блок и не указал модификаторов явно, то это безусловный факт того, что модификаторов у блока нет. И никакой одноименный блок-предок не влияет на эту ситуацию.

Если я правильно понял тебя, то ты уверен, что модификаторы блока должны приезжать к вложенному элементу одноименного блока без указанных модификаторов. Так?