Добавление аргументов ссылочного типа, управление значением аргументов шаблона и привязка события

Работа с ссылочными аргументами

Теперь попробуем управлять значениями аргументов шаблона "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, } ...

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