Добавление аргументов ссылочного типа, управление значением аргументов шаблона и привязка события
Работа с ссылочными аргументами
Теперь попробуем управлять значениями аргументов шаблона "period", "feq" и "pause" в подшаблоне templates/blocks/planet.tmpl+earth.
Для этого мы будем использовать ссылочные аргументы, которые создаются функцией fcf.argRef(), при обращении к данному типу аргумента выполняется не прямое чтение или запись значения, а обращение к данным на которые указывалось при создании аргумента.
Для начала мы создадим в основном шаблоне :templates/blocks/planet.tmpl экземпляры аргументов "period", "feq" и "pause" c немного измененными значениями, что бы убедиться, что наш механизм работает.
Файл :templates/blocks/planet.tmpl
...
//~ARGUMENTS
{
fcfStyleInner: fcf.argVal("display: block; overflow: hidden; width: @{{args.width}}@; height: @{{args.height}}@"),
width: "100%",
height: "300px",
starsCount: 100,
stars: fcf.argProg(),
feq: 5,
period: 2,
pause: false,
}
...
И передадим эти значения в подшаблон templates/blocks/planet.tmpl+earth. Но не прямым значением а ссылочным аргументом. Для этого снова отредактируем шаблон :templates/blocks/planet.tmpl.
Файл :templates/blocks/planet.tmpl:
...
//~TEMPLATE
<div class="planet-container">
<div class="star-container">
%{{ for(let i = 0; i < args.stars.length; ++i) { }}%
<div
class="star"
style="left:@{{args.stars[i].left}}@%; top: @{{args.stars[i].top}}@%; animation-duration: @{{args.stars[i].duration}}@s; animation-delay: @{{args.stars[i].delay}}@s;"></div>
%{{ } }}%
</div>
<div class="planet-sun-container">
<div class="planet-sun-container-item">
<div class="planet-sun"></div>
</div>
</div>
@{{ render.template("+earth", {period: fcf.argRef("period"), feq: fcf.argRef("feq"), pause: fcf.argRef("pause") }); }}@
</div>
...
Теперь если мы будем менять значения в основном шаблоне во время работы приложения, аргументы подшаблона также поменяются.
Для динамического изменения аргументов шаблона бы будем использовать шаблон редактора целочисленных значений @controls:int-edit из пакета fcfControls.
Добавим еще один подшаблон "controls", в котором и разместим элементы управления.
Конец файла :templates/blocks/planet.tmpl
...
//~OPTIONS controls
{
autoUpdate: true,
}
//~ARGUMENTS controls
{
fcfClassInner: "planet-controls-container",
}
//~TEMPLATE controls
<p>
<div class="planet-title-control">!{{Period}}!: </div>@{{ render.template("@controls:int-edit", {value: fcf.argRef("period"), min: 1, width: 80})}}@
</p>
<p>
<div class="planet-title-control">!{{Frequency}}!: </div>@{{ render.template("@controls:int-edit", {value: fcf.argRef("feq"), min: 1, width: 80})}}@
</p>
<p>
<div
class="planet-play-control"
fcfEventClick="wrapper.setArg('pause', !wrapper.getArg('pause'))"
>
@{{ args.pause ? ` >>> ${fcf.t("Play")} <<<` : `>>> ${fcf.t("Pause")} <<<` }}@
</div>
</p>
И выполним вывод нашего нового подшаблона, передав ссылки на аргументы, которыми мы будем управлять.
Файл :templates/blocks/planet.tmpl:
...
//~TEMPLATE
<div class="planet-container">
<div class="star-container">
%{{ for(let i = 0; i < args.stars.length; ++i) { }}%
<div
class="star"
style="left:@{{args.stars[i].left}}@%; top: @{{args.stars[i].top}}@%; animation-duration: @{{args.stars[i].duration}}@s; animation-delay: @{{args.stars[i].delay}}@s;"></div>
%{{ } }}%
</div>
<div class="planet-sun-container">
<div class="planet-sun-container-item">
<div class="planet-sun"></div>
</div>
</div>
@{{ render.template("+earth", {period: fcf.argRef("period"), feq: fcf.argRef("feq"), pause: fcf.argRef("pause") }); }}@
@{{ render.template("+controls", {period: fcf.argRef("period"), feq: fcf.argRef("feq"), pause: fcf.argRef("pause") }); }}@
</div>
...
Если все сделано правильно, то в браузере мы увидим почти законченное приложение. Но давайте, разберемся, что выполнялось в подшаблоне +controls
Для управления значениями "feq" и "period" мы использовали шаблон редактора для типа integer (шаблон @controls:int-edit). В качестве основного аргумента "value" мы передали ссылку, а так же ограничили минимальное вводимое значение аргументом min до 1. И для красоты установили его ширину равную 80 пикселям.
Обработка событий в теле шаблона
Теперь рассмотрим управление состоянием аргумента "pause". Его значение выполняется прямо в обработчике DOM события click. В фреймворке могут использоваться атрибуты обработки событий, которые начинаются с префикса fcfEvent, за которым следует имя DOM события. Данный механизм сделан для удобства, так как в нем доступны объекты самого шаблона wrapper, владельца шаблона parent и конечно объект самого события event.
В обработчике события fcfEventClick мы просто меняем значение аргумента "pause" на противоположное. Для этого применяются методы wrapper.getArg() и wrapper.setArg()
Вывод надписи Pause/Play выполняется в конструкции вывода @{{}}@ с применением перевода на язык пользователя. Для этого используется функция fcf.t().
Теперь можно вернуть аргументы "period" и "feq" к нормальным значениям.
Файл :templates/blocks/planet.tmpl:
...
//~ARGUMENTS
{
fcfStyleInner: fcf.argVal("display: block; overflow: hidden; width: @{{args.width}}@; height: @{{args.height}}@"),
width: "100%",
height: "300px",
starsCount: 100,
stars: fcf.argProg(),
feq: 60,
period: 10,
pause: false,
}
...
Запустите в браузере приложение и убедитесь как меняются значения аргументов шаблона.