До сих пор не могу понять магию apply, applyNext, applyCtx хотя ни раз читал ман по ним
Вообще мне нужно изменить элемент на ссылку, если в параметрах есть url, я сделал так
block('nav').elem('item')
(
    match(this.ctx.url)
    (
        function()
        {
            this.ctx.block = 'link';
            delete this.ctx.elem;
            this.ctx.mix   = [
                {
                    block: this.block,
                    elem: 'item'
                }
            ];
            applyCtx(this.ctx);
        }
    )
);
Получаю бесконечную рекурсию - [RangeError: Maximum call stack size exceeded]
Сейчас я поставил такой костыль:
block('nav').elem('item')
(
    match(this.ctx.url && !this.ctx._prepared)
    (
        function()
        {
            this.ctx.block     = 'link';
            this.ctx._prepared = true;
            delete this.ctx.elem;
            this.ctx.mix   = [
                {
                    block: this.block,
                    elem: 'item'
                }
            ];
            applyCtx(this.ctx);
        }
    )
);
Как сделать правильно?
На сколько я знаю с рекурсией обещали разобраться в следующих релизах. А пока про такой костыль где то даже в доках было написано
вообще должно работать как-то так:
я добавил
.def()(именно в шаблонах по дефолтной моде имеет смысл применятьapplyCtx) и немного исправил логику с редактированием контекста прямо inplace (так не стоит делать, потому что BEMJSON API блока и элемента могут не совпадать и лучше явно создавать блок)Также было замечено, что applyCtx по дефотной моде не вызывало проблем, на как только захотелось использовать match условие, появилась рекурсия, спасибо за подсказку использования def и match вместе, завтра попробую этот вариант и отпишу
Не очень понял смысл фразы "так не стоит делать" в контексте. Не стоит делать как было написано у меня из-за того что api блока и элемента может не совпадать, правильно я понял?
Что почитать, чтобы наконец понять как работают методы apply, а то пишу больше на интуиции, пробуя разные варианты. Может это относится к xslt и его почитать или что?
Например ты написал, что applyCtx работает с дефолтной модой, а где это можно прочитать?
У меня сложилось впечатление, что отличие applyNext от applyCtx лишь в том, что аpplyNext работает с текущим this, а applyCtx с тем, что ему передали в виде аргумента. Еще заметил много где пишут return applyNext, хотя он ничего не возвращает
Я на интуиции написал больше трех проектов)) значит в правильно делаешь)
@4ok попробуй скомпилить пустой шаблон, в коде можно покопаться и разобраться :) Я так делал в https://github.com/alexbaumgertner/bare-bemhtml/blob/master/bare-bemhtml.js :)
Например, можно увидеть, как сохраняется контекст https://github.com/alexbaumgertner/bare-bemhtml/blob/master/bare-bemhtml.js#L391 а
applyпо сути – это вызов функции, возвращающей шаблонизированные данные https://github.com/alexbaumgertner/bare-bemhtml/blob/master/bare-bemhtml.js#L18А если смотреть исходниики не компилированные, то вот
def() https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/i-bem.bemhtml#L322
Вот вызов стандартных мод https://github.com/alexbaumgertner/bare-bemhtml/blob/master/bare-bemhtml.js#L56-L121
В общем, посмотрите свой скомпилированый bemhtml, можно для удобочитаемости прогнать через http://jsbeautifier.org
попробуйте bh, он кажется немного проще
Где почитать bh?
https://github.com/enb-make/bh
Срезюмирую про apply*.
apply,applyNextиapplyCtx— это синтаксические конструкции, первые две относятся кxjst, третья кBEMHTML. Разница между ними следующая:apply. ВapplyNextавтоматически выставляется защита от зацикливания, так что вы гарантировано не вернетесь в этот же шаблон.applyNext, где по пустой моде вthis.ctxприсваивается объект, переданный в качестве параметра.Соответственно
applyпрактически не нужен никогда,applyNextиспользуется тогда, когда вы хотите получить предыдущий результат работы этого шаблона, аapplyCtxнужен тогда, когда вы хотите заиспользовать новый кастомный, динамически сгенерированныйbemjson.Об этом хорошо написано в Референсе по BEMHTML.
Написал, что происходит в моде
defhttps://github.com/bem/bem-core/issues/643