Vložení JS/CSS z komponenty do šablony
- Šaman
- Člen | 2659
Ahoj, název vlákna není přesný, ale chtěl jsem, aby byl co nejvýstižnější. Jak řešíte komponenty, nebo továrny na formuláře, které mají vlastní JS/CSS?
Všechny diskuze, co jsem našel, jsou 5 let staré, tak předpokládám, že frontenďáci už mají nějaký osvědčený způsob, který nepotřebuje diskutovat :)
P.S. Teď mi nejde o to, aby se scripty načítaly odněkud z vendoru, nebo
/app
. Samotné scripty budou ve /www
na přesně
definované adrese pomocí boweru. Jde mi jen o to, že třeba JS který je
potřeba pro konkrétní formulář se závislými selectboxy, nechci načítat
ani v @layoutu (kanón na vrabce), ani ručně v šabloně, která ten
formulář používá (tam na to mohu zapomenout).
- Pavel Kravčík
- Člen | 1195
Nedávno jsem to řešil s pomocí webloaderu, že jsem si udělal „balíčky“.
js:
base:
files:
- bootstrap-3.3.1.min.js
- netteForms.js
- spinner.ajax.js
default:
files:
- jquery.confirm.js
- bootstrap-filestyle.js
- jquery.autocomplete.min.js
- jquery.elevate-zoom-3.0.8.min.js
dochazka:
files:
- dochazka/dochazka.js
V základní šabloně je něco jako {component cssBase}
{component cssExtend}
a v presenteru kde potřebuji jiné styly si
přetížím metody createComponentCssExtend a ta pak vypadá takhle:
protected function createComponentExtendJs()
{
return $this->webLoader->createJavaScriptLoader('dochazka');
}
Tj. pro každý presenter si jednoduše připravíš správný guláš js.
- Šaman
- Člen | 2659
No, to si mohu udělat i ručně. (Načíst správné JS v šabloně
presenteru.)
Já bych docela rád docílil toho, že příslušný JS zapíšu jen do
šablony (nebo php kódu) komponenty a pak mi bude jedno, kam tuto komponentu
umístím. Protože když je větší množství komponent různě po celém
projektu, tak už nevím, která potřebuje dolinkovat nějaký JS/CSS a
která ne.
- Šaman
- Člen | 2659
Díky za odpovědi, ale nakonec se jako nejjednodušší ukázalo staré řešení
od Tharose.
Trochu jsem si to upravil, rozšířil o možnost načítat i CSS (ačkoliv to
nedoporučuji) a výsledek je tento:
$(function () {
// basePath nastavíme buď pomocí data-atributu při načtení scriptu
// <script src="{$basePath}/js/easyLoader.js" id="easyLoader" data-basepath="{$basePath}"></script>
var basepath = $('#easyLoader').data('basepath');
// nebo se použije adresa serveru
if (basepath === undefined) {
basepath = window.location.protocol + "//" + window.location.host + "/";
}
// načtení CSS (na CSS se tento loader nedoporučuje používat, protože je závislý na JS a načtení stylů je zpožděné)
$('[data-css]').each(function (index, element) {
var style = $(element).data('css');
if (style instanceof Array) {
$.each(style, function (index, style) {
head.load(basepath + style);
})
} else {
head.load(basepath + style);
}
});
// načtení JS
$('[data-js]').each(function (index, element) {
var script = $(element).data('js');
if (script instanceof Array) {
$.each(script, function (index, script) {
head.js(basepath + script);
})
} else {
head.js(basepath + script);
}
});
});
<!-- @layout.latte -->
<script src="{$basePath}/bower/jquery/dist/jquery.min.js"></script>
<script src="{$basePath}/bower/headjs/dist/1.0.0/head.load.min.js"></script>
<script src="{$basePath}/js/easyLoader.js" id="easyLoader" data-basepath="{$basePath}"></script>
<!-- template.latte -->
<h1 data-css="/css/pokus.css">Pokusy</h1>
<div data-js="/js/bootstrap.tab.history.js">…</div>
- Je to vyzkoušené na aktuálních verzích FF, Chrome, Exploreru a Opery. Mělo by to být kompatibilní i se staršími (nikoliv archaickými) prohlížeči.
- Pokud máte nastavený server tak, že v adrese není /www (nebo jiný kus adresářové stuktury), tak není potřeba přenášet tu basepath v data atributu.
- Pokud máte zkušenosti s JS, napadá vás nějaký zásadní problém, proč tohle řešení nepoužívat? A co na to @Tharos, který s tím má osobní zkušenosti? Koukal jsem, že na svém GitHubu už to smazal.
- Repozitář a možná bower balíček tomu vytvořím, až to otestuji v praxi. Zatím mi na tom běží jen pokusná miniaplikace.
Pozn. Celá část s basepath
je možná úplně zbytečná,
čitelnější mi připadá předávat rovnou celou cestu už z šablony.
<!-- @layout.latte -->
<script src="{$basePath}/bower/jquery/dist/jquery.min.js"></script>
<script src="{$basePath}/bower/headjs/dist/1.0.0/head.load.min.js"></script>
<script src="{$basePath}/js/easyLoader.js"></script>
<!-- template.latte -->
<h1 data-css="{$basePath}/css/pokus.css">Pokusy</h1>
<div data-js="{$basePath}/js/bootstrap.tab.history.js">…</div>
Editoval Šaman (26. 11. 2015 4:15)
- Jan Mikeš
- Člen | 771
Ahoj, ja toto resim tak, ze mam v hlavnim @layout.latte tesne pred </body> nasledujici blok:
{control js}
{block js}{/block}
{control js} je webloader
V pripade, ze potrebuji nejaky dalsi js je to jednoduche, v sablone, kde jej potrebuji rozsiruji
{block js}
{include #parent}
<script ...>
{/block}
Pokud se jedna o sablonu komponenty, ve ktere chci js/css mit, pak pridavam komponente view js/css a tento view pak prislusnym renderem renderuji v presenteru takze v konecnem vysledku vypada nejak takhle
// MyPresenter.default.latte
{block js}
{include #parent}
<script ...>
<script ...>
{control myComponent:js}
{control myComponentXy:js}
{/block}
// MyComponent\js.latte
<script ...>
Editoval Lexi (26. 11. 2015 7:42)
- Šaman
- Člen | 2659
Jenže právě toho se chci vyvarovat. Presenter přece neví, že nějaká
komponenta má i JS. Když k nějaké komponentě připíšu script, tak
nechci prohledávat celý projekt a u každého výskytu přidat do šablony
presenteru i {control myComponent:js}
.
Ten webloader je jedno řešení, dynamické donačítání scriptů je druhé
řešení. A na občasné donačtení malých JS (typicky oživení
konkrétního formuláře) mi zatím to druhé řešení vyhovuje víc.
- CZechBoY
- Člen | 3608
A když si uděláš svojí komponentu, která bude spravovat js + css
komponent?
Ke každý komponentě si tu službu přidáš a budeš po ní požadovat, ať
tyhle js a css knihovny přidá.
Ta služba potom bude spravovat pořadí, ve kterým se mají js a css načíst,
aby se to nějak nepo**lo … :)
- Demo
- Člen | 1
Ahoj,
v nette jsem začátečník, ale narazil jsem na stejný problém. Nepokročilo
se od posledního příspěvku k nějakému elegantnějšímu vestavěnému
řešení? Přišlo by mi smysluplné mít v @layout třeba block {block
dalsiScripty} a z šablony komponenty pak jen do tohoto bloku přidat další
položku/obsah. Změna v šabloně komponenty by se tak automaticky projevila
všude, kde je jí třeba. Protože komponent může být v presenteru mnoho,
tak by se obsahy skládaly…
Díky,
Demo
- AntiCZ
- Člen | 13
Ja jsem to vyresil pres tovarnu komponenty, ktera v konstruktoru setuje do servisy svoje jmeno. A potom si v BasePresenteru v beforeRenderu projdu seznam vyzadanych komponent.
- Nevyhody
- To ze probehl inject v Presenteru, jeste neznamena, ze bude kompopenta vyrendrovana, treba s tim v JS pocitat.
- U vnorenych komponent je potreba predavat tovarnu na komponentu jako zavislost rodici.
Editoval AntiCZ (2. 6. 2018 8:55)