<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Constructorul Zonal</title> <atom:link href="http://192.168.1.170/feed/" rel="self" type="application/rss+xml" /><link>http://constructorul-zonal.xhost.ro</link> <description>dezvoltare web, programare, IT, societate, filozofie, politică</description> <lastBuildDate>Mon, 11 Nov 2024 05:28:56 +0000</lastBuildDate> <language>ro</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>TypeScript Lite</title><link>http://constructorul-zonal.xhost.ro/typescript-lite/</link> <comments>http://constructorul-zonal.xhost.ro/typescript-lite/#comments</comments> <pubDate>Tue, 20 Feb 2024 02:49:25 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[societate]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=69</guid> <description><![CDATA[Sunteți în căutarea limbajului de programare perfect pentru a vă scrie aplicația proprie? și atâția experți v-au spus că nu există unul, doar anumite instrumente pentru anumite sarcini. Ba da, există, este imaginația dvs.! Trebuie doar să știți cum să o împărtășiți și celorlalți. Paradigma tipurilor Din punct de vedere istoric, limbajele de programare s-au [&#8230;]]]></description> <content:encoded><![CDATA[<p>Sunteți în căutarea limbajului de programare perfect pentru a vă scrie aplicația proprie? și atâția experți v-au spus că nu există unul, doar anumite instrumente pentru anumite sarcini. Ba da, există, este imaginația dvs.! Trebuie doar să știți cum să o împărtășiți și celorlalți.</p><h2>Paradigma tipurilor</h2><p>Din punct de vedere istoric, limbajele de programare s-au împărțit în două categorii majore: un subset mai  mic al limbajelor dinamice sau fără tip (de date) precum PHP, JavaScript, Python sau Ruby și unul mai mare de limbaje cu tip (de date) începând cu C, C++, Pascal, Fortran, Java, C#, Go sau Rust și ajungând la limbaje augmentate cu tip precum TypeScript sau Dart. Totuși, limbajele dinamice folosesc tipurile pentru manipularea datelor și chiar efectuează anumite verificări de tipuri la rulare, în timp ce limbajele cu tip sau statice ajung să ruleze de regulă sub formă binară, în care nu se efectuează implicit verificarea tipurilor pentru zonele de memorie reprezentând variabilele sau structurile de date ce au fost deja verificate în timpul compilării. Deci, tipurile de date sunt întotdeauna subînțelese atunci când scriem cod, dar nu atât de relevante pentru mașina ce execută codul. Aceasta deoarece tipul e un concept uman situat în vecinătatea unora similare precum categorie, fel, sortiment, clasă ș.a.m.d..<br /> Deși limbajele statice au utilizat sintaxa mai strictă pentru a efectua o mai bună verificare a erorilor, compilare și optimizări (ahead-of-time), limbajele dinamice le-au ajuns din urmă ca facilități și performanță folosind tehnici precum compilare just-in-time și trasee de execuție. Pentru un set limitat de tipuri de date ale unei variabile din cod, majoritatea scenariilor de utilizare a acestora se invalidează de fapt la execuția programului.<br /> Într-un limbaj de programare mai natural, denumirea variabilelor ar avea înțeles drept cuvinte, astfel încât împachetatorul/compilatorul s-ar putea informa dintr-un dicționar lingvistic uman pentru a efectua detectare suplimentară a tipurilor. Noi, ca oameni, profităm de celelalte informații senzoriale, de cunoștințe și de context pentru a infera și mai bine tipurile obiectelor. Un compilator, parser sau IDE deștepte pot utiliza interacțiunea/prompting-ul sau asistență AI pentru a finaliza identificarea tipurilor la dezvoltare.<br /> Îndelungata dezbatere a exprimării sintactice a tipurilor de-a lungul codului poate deveni, până la urmă, doar o chestiune de a tasta sau a nu tasta.</p><h2>O idee bună readusă la viață</h2><p>După cum este descris în <a title="TypeScript Lite" target="_blank" href="https://github.com/zonebuilder/tslite-node">pagina proiectului TypeScript Lite</a>, acest pachet Node.JS (TSLite) convertește un arbore de cod sursă JavaScript într-un arbore de cod sursă TypeScript.<br /> Aceasta este posibil deoarece TSLite folosește una din cele mai simple forme de adnotare a tipurilor: notația prefix.<br /> Ideea denumirii prefixate a identificatorilor, numită de asemenea notația maghiară, a fost adusă în urmă cu câteva decenii de către mari companii software pentru unele din platformele lor interne cum ar fi Microsoft MFC, Win32 API sau Borland OWL. Deoarece notația era folosită la nivel de platformă, iar companiile insistau pe construirea canonică a prefixelor necesare, dezvoltatorii s-au confruntat destul de repede în a se documenta cu un mare număr de elemente prefix consistând în principal din consoane, care i-au făcut să ironizeze despre învățarea de fapt a unei limbi străine, iar practica de a folosi denumirea cu prefixe s-a estompat.<br /> Prin contrast cu implementarea originală, ce are totuși meritul unui bun început, notația prefix a TSLite are următoarele caracteristici cheie:</p><ul><li>Prefixele sunt definibile utilizator la nivelul unui proiect via fișier de configurare. E posibil de asemenea să se specifice prefixele la nivelul unui fișier via bloc de comentariu dedicat.</li><li>Utilizatorul poate alege prefixe cu litere mici de orice lungime sau chiar cu potrivire cu un șablon regex. Aceste prefixe se aplică variabilelor cu tip de date prestabilit sau definit de utilizator, dar și unor variabile alese specific.</li><li>În modulele CommonJS și ES, variabilele importate și exportate și funcțiile top-level pot și ar trebui exceptate de la denumirea cu prefix. TypeScript va infera tipurile acestora de la modulele importate și de la semnăturile funcțiilor. Nu se va aplica notația prefix la membrii unui obiect/clasă/map. Pentru aceste structuri, pot fi utilizate fișiere de definiții TS externe sau comentarii bloc structurale JSDoc.</li></ul><p>Un exemplu al unui stub de aplicație convențională ExpressJS ce va fi convertit la TypeScript pe baza prefixelor variabilelor și a unui fișier de configurare, este afișat mai jos.</p><h4>app.js</h4><pre class="brush:js">/* tslite-add
 * interface Request { app: any; }
 * interface Response { locals: any; render: Function; }
 */
const cookieParser = require('cookie-parser')
const express = require('express')
const httpErrors = require('http-errors')
const logger = require('morgan')
const path = require('path')

const indexRouter = require('./routes/index')

/// @ts-ignore
const app = express()

app.set('views', path.join(__dirname, 'views'))
// view engine setup
app.set('view engine', 'ejs')

app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())

app.use(express.static(path.join(__dirname, 'public')))

app.use('/', indexRouter)

// catch 404 and forward to error handler
app.use((req, res, next) =&gt; {
    next(httpErrors(404))
})

// error handler
app.use((err, req, res, next) =&gt; {
    // set locals, only providing error in development
    res.locals.message = err.message
    res.locals.error = req.app.get('env') === 'development' ? err : {}

    // render the error page
    /// @ts-ignore
    res.status(err.status || 500)
    res.render('error')
})

module.exports = app</pre><h4>app.ts</h4><pre class="brush:js">interface Request { app: any; }
interface Response { locals: any; render: Function; }
const cookieParser = require('cookie-parser')
const express = require('express')
const httpErrors = require('http-errors')
const logger = require('morgan')
const path = require('path')

const indexRouter = require('./routes/index')

/// @ts-ignore
const app = express()

app.set('views', path.join(__dirname, 'views'))
// view engine setup
app.set('view engine', 'ejs')

app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())

app.use(express.static(path.join(__dirname, 'public')))

app.use('/', indexRouter)

// catch 404 and forward to error handler
app.use((req: Request, res: Response, next: Function) =&gt; {
    next(httpErrors(404))
})

// error handler
app.use((err: any, req: Request, res: Response, next: Function) =&gt; {
    // set locals, only providing error in development
    res.locals.message = err.message
    res.locals.error = req.app.get('env') === 'development' ? err : {}

    // render the error page
    /// @ts-ignore
    res.status(err.status || 500)
    res.render('error')
})

module.exports = app</pre><h4>tslite.json</h4><pre class="brush:js">{
  &quot;input&quot;: [&quot;express-app&quot;, &quot;sample.js&quot;],
  &quot;output&quot;: &quot;../src-ts&quot;,
  &quot;matcher&quot;: [
    &quot;/\\.js(x?)$/i&quot;,
    &quot;.ts$1&quot;
  ],
  &quot;prefixes&quot;: {
    &quot;a&quot;: &quot;any[]&quot;,
    &quot;b&quot;: &quot;boolean&quot;,
    &quot;f&quot;: &quot;Function&quot;,
    &quot;n&quot;: &quot;number&quot;,
    &quot;o&quot;: &quot;any&quot;,
    &quot;s&quot;: &quot;string&quot;,
    &quot;$e[0-9]*&quot;: &quot;any&quot;,
    &quot;$[i-nx-z][0-9]*&quot;: &quot;number&quot;,
    &quot;req&quot;: &quot;Request&quot;,
    &quot;res&quot;: &quot;Response&quot;,
    &quot;$next&quot;: &quot;Function&quot;,
    &quot;$err&quot;: &quot;any&quot;
  }
}</pre><h4>tsconfig.json</h4><pre class="brush:js">{
  &quot;compilerOptions&quot;: {
    &quot;outDir&quot;: &quot;dist&quot;,
    &quot;strictNullChecks&quot;: false,
    &quot;target&quot;: &quot;es2016&quot;,
    &quot;module&quot;: &quot;commonjs&quot;,
    &quot;esModuleInterop&quot;: true,
    &quot;forceConsistentCasingInFileNames&quot;: true,
    &quot;strict&quot;: true,
    &quot;skipLibCheck&quot;: true
  }
}</pre><p>Fiind generat de un utilitar automat (yeoman), codul JS este păstrat nemodificat, dar puteți aplica notația prefix cu ușurință la toate variabilele dorite și vedea imediat adnotările suplimentare TS rezultate.<br /> Deși pachetul TSLite e o aplicație consolă Node.JS, poate fi rulat uniform pe proiecte de cod mobile, browser, server sau pe orice proiect ES5/ES6. Un flux de lucru tipic ce poate fi ales este: scrieți mai întâi codul dvs. ES6 și verificați-l cu ESLint, apoi convertiți codul folosind TSLite și verificați-l cu TSC.<br /> Deoarece acest set de unelte vă permite să scrieți cod JavaScript robust ce va fi convertit într-un singur pas în orice dialect al adnotării TS, ca de exemplu AssemblyScript, puteți folosi notația prefix pentru a transforma automat spre un cod sursă cu tipuri/static.</p><h2>Stenografie</h2><p>Oamenii au folosit metoda notației prescurtate, denumită și stenografie, încă din antichitatea greacă clasică(cca. 400 î.e.n.), pentru a înregistra mesajele vorbite în scris cu viteză comparabilă cu cea a vorbitorului. Despărțindu-se de erele greacă și romană, stenografia a cunoscut o evoluție majoră în secolele al 18-lea și al 19-lea, cu forme de notație prescurtată bazate pe figuri geometrice (cercuri, linii, punte) și mai apoi pe simboluri pentru foneme (sunetele rostite). Cea din urmă s-a standardizat și, în câteva decenii, a fost adoptată în mai bine de 16 limbi din Europa, America și Asia. În același timp, stenografia, ortografia (a semnelor de punctuație și a abrevierilor) și notația simbolică din științe au împrumutat puternic una de la alta, maturizându-se și devenind concomitent metodologii standard. Ceea ce a început ca necesitate de viteză în scris, a devenit o abordare universală de a transmite informație relevantă, concisă și precisă pentru oamenii din întreaga lume.<br /> Un secol mai târziu, creatorii limbajelor de programare de generația a 3-a s-au inspirat din principiile notațiilor prescurtată și simbolică, construind prima sintaxă cu aspect uman pentru ceea ce încă era perceput, la cel moment, ca un ambalaj mai prietenos în jurul logicii computaționale și a seturilor de instrucțiuni cod-mașină. Datorită universalității lor, unele dintre aceste limbaje au devenit coloana vertebrală a programării moderne, fiind adoptate în orice colț al lumii, unde au popularizat un avans tehnologic comun și slang-ul pe care îl numim azi &#8221; &#8220;Engleză IT &#8220;.<br /> Este de presupus că uneltele de codare rezolvă în special probleme tehnice, ele constituie totuși, pretutindeni, și o modalitate puternică de a colabora și de a comunica, la fel cum notațiile prescurtată și simbolică erau deja cu un secol înainte de era digitală.</p><h2>Limbajul Script</h2><p>Având în vedere argumentele anterioare, se poate spune că limbajul de programare de scop general al viitorului apropiat va avea următoarele caracteristici cheie:</p><ul><li>Provine dintr-o abordare centrată pe om bazată pe matematică și fizică spre deosebire de cea bazată pe setul de instrucțiuni ale mașinii. Algoritmica, uneltele și AI-ul curente sunt capabile să traducă de la sintaxa exprimării umane la logica de calcul. Este de așteptat ca programarea viitoare a majorității sistemelor se va ocupa doar de problema de business, permițând în același timp un spectru complet de input-uri umane în afară de scriere.</li><li>Folosește cuvinte scurte, abrevieri (ale englezei internaționale simplificate de ex.) și simboluri pentru cuvintele cheie și operatori, păstrând un vocabular al limbajului ușor de înțeles, aderând totodată la principiul notației prescurtate de a scrie concis și precis. Codul e scris într-un fel de limbaj universal, dar se citește verbal în limba naturală a cititorului (asemănător cum este citit pseudo-codul în prezent).</li><li>țintește runtime-urile atât compilat cât și interpretat. Codul introdus original de către om este considerat sursa de adevăr. Pentru oricare din ținte, poate fi generat un cod augmentat în mod automat sau cu ajutorul utilizatorului. Codul augmentat e legat de segmente sau unități logice (de factor a câteva linii) ale codului original. Modificarea unui segment al codului original invalidează fragmentul corespunzător din codul augmentat, care va trebui să fie regenerat în funcție de cerințele țintei.</li><li>Are un framework pentru controlul structurilor de date și a fluxului programului numit constrângerile programului. Acest framework al constrângerilor programului descrie și configurează următoarele: tipurile datelor, forma obiectelor (structura), validarea câmpurilor de date, ierarhia erorilor, prioritatea modulelor (secvența), configurarea concurenței etc.. este secundar la și se aplică imediat după codul original, afectând astfel orice cod augmentat. Este disponibil pentru a fi folosit și la rulare, luând parte efectiv în programul ce rulează.</li></ul><p>Software-ul ce permite programarea cu acest limbaj are un set modern de unelte dezvoltator, incluzând: lint-are, compilare, audit de cod și generare de teste, împachetare, emularea rulării (sandbox). Pentru toate etapele în care se generează o anume formă de cod sau de program, există trasabilitate, iar factorul uman poate interveni dacă este necesar.<br /> Limbajul, pe care îl vom denumi simplu &#8220;Script&#8221;, facilitează utilizarea structurilor de date high-order și a algoritmilor (ca în C++ STL), wrapper-ere pentru servicii asincrone și web, diverse instrumente pentru procesarea datelor și AI, prin includerea codului acestora în biblioteca utilizator standard.<br /> Multe dintre limbajele de scop general de astăzi au obținut optimizările interne pentru faza de compilare sau just-in-time, biblioteci elegante și disponibile gratuit pentru domenii de interes comun și o bună ergonomie pentru dezvoltatorul ce urmărește rezolvarea problemelor complexe. Învățarea de bază a acestora a devenit trivială datorită generării AI a codului  și interșanjabilitatea lor evidentă datorită capabilităților excelente ale transpiler-elor de cod de azi. În loc de a învăța zece dialecte sau zece moduri de a utiliza un instrument avansat care este platforma noastră de soluții software, o persoană se poate concentra la a stăpâni limbajul de scop general ce țintește toate runtime-urile comune fie compilate sau interpretate și oferă setări flexibile de optimizare, biblioteci specializate de business și tehnologie și un ecosistem universal gata să implementeze orice demers creativ.</p><h2>Un cerc complet</h2><p>Imaginați-vă că pe tastatura computerului dvs. aveți și două rânduri suplimentare de taste ce sunt figuri geometrice regulate și simboluri cunoscute ca cele pe care le utilizăm în mod curent. Oricare dintre aceste douăzeci de taste simbol inițiază și finalizează o secvență de maxim trei apăsări de taste ce vor deveni, în final, un simbol geometric. Prima apăsare va desena figura tastată în partea de jos la poziția de tastare, a doua apăsare va desena figura sau simbolul tastat în partea de sus (poate cu o ușoară suprapunere temporară), iar a treia apăsare se va desena ca superscript sau subscript (printr-o tastă modificator) în cadrul aceluiași simbol geometric ce va lua locul unui singur caracter. Încă de la prima apăsare, o listă de tip popup va apărea lângă poziția de tastare conținând simboluri geometrice finale sortate după similaritate cu secvența de tastare. Aceasta este o listă cu selecție individuală în care fiecare element este un simbol geometric urmat de un cuvânt în limba nativă sau preferată a utilizatorului, dar cu același înțeles global când e tradus. Selecția din listă se mută sau se rafinează pe măsură ce tastați secvența sau prin navigare utilizator (taste săgeți, mouse, atingere, dictare etc.). secvența se termină fie la a treia tastă apăsată, fie la apăsarea unei taste terminale (de ex. Enter) sau o tastă caracter//delimitator alta decât cele douăzeci, sau alegând un element din listă.<br /> Simbolul final nu este o juxtapunere directă a figurilor tastate, ci este mai degrabă indicat de succesiunea lor și de compunerea acestora, arătând și comportându-se de fapt ca un font truetype. Exemple ale unor astfel de simboluri finale pot fi: un pătrat urmat de un triunghi așezat produce simbolul &#8216;casă &#8216;, un pătrat urmat de un triunghi cu capul în jos produce simbolul &#8216;arbore &#8216;, o linie de subliniere urmată de un cerc produce simbolul &#8216;răsărit &#8216;, o linie de subliniere urmată de un cerc și apoi de un asterisc produce simbolul &#8216;apus &#8216;.<br /> Scriptul simbolic introdus va purta de asemenea un transcript în cuvinte într-o limbă vorbită implicită (ex. engleza), care se traduce cuvânt-la-cuvânt la cuvintele alese de utilizatorul care a tastat.<br /> Folosită la scrierea codului, această metodă de tastare permite utilizarea simbolurilor geometrice peste tot unde folosim cuvinte pentru denumiri precum la variabile, funcții, clase, nume membri etc.. aceasta poate funcționa la codul propriu-zis în timp ce este păstrat formatul text pentru schimbul de date precum JSON sau XML.<br /> Reamintiți-vă că scrierea latină provine în ordine din greacă, feniciană, arameică și, în ultimă instanță, din hieroglifele egiptene, iar schițele abstracte preced scrisul ca și concept al minții umane. De asemenea, diverse ilustrări SF prezintă un grup de figuri sau simboluri geometrice ca fiind o secvență de comandă pentru activarea unor tehnologii ale viitorului îndepărtat.<br /> Se spune că forma perfectă din univers este cercul, de aceea și utilizarea sa constantă în arte, frumusețe și chiar și în științe. planetele din fiecare câmp gravitațional al stelei acestora zboară prin spațiu cu pierdere minimă de energie pe traiectorii închise și aproape circulare. Chiar și minusculul electron se rotește mereu în jurul nucleului atomului înăuntrul unei fâșii închise numită nivel energetic.<br /> Se pare că traseul sau calea circulară e una dintre legile fundamentale ale universului. Unii oameni spun că însăși istoria umană tinde să se repete în cicluri după câteva sute sau mii de ani.<br /> Dar unii dintre noi totuși au observat că planetele când își închid traiectoria nu se întorc în același punct din univers deoarece stelele și întregi galaxii au propriile trasee de călătorie. și minusculul electron are tendința de a sări de pe un nivel energetic pe altul, ba chiar să părăsească atomul. Dacă desenați un cerc în nisip, nu se va închide în același punct din spațiu deoarece planeta s-a rotit între timp. Cercurile ființelor vii auto-evoluează în spirale.<br /> Am aflat așadar că există o a doua lege fundamentală în univers, cel puțin la fel de importantă ca și prima, numită evoluție.<br /> Pentru acei dintre noi ce prețuiesc cunoașterea umană, nu trebuie să fie loc de a ne fi frică de căi închise, sau că istoria s-ar putea repeta.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/typescript-lite/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Cele 3 modele de date</title><link>http://constructorul-zonal.xhost.ro/cele-3-modele-de-date/</link> <comments>http://constructorul-zonal.xhost.ro/cele-3-modele-de-date/#comments</comments> <pubDate>Wed, 07 Jun 2023 03:14:18 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[Dezvoltare web]]></category> <category><![CDATA[JavaScript]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=60</guid> <description><![CDATA[Odată cu ascensiunea web-ului ca platformă de programare, în aplicațiile web au fost implementate o serie de metode de proiectare începând cu MVC, MVVM și ajungând la legături de date în UI, stocarea centralizată a stării și GraphQL. Dar ceea ce devine o tendință majoră în dezvoltarea software este abordarea centrată pe date de a [&#8230;]]]></description> <content:encoded><![CDATA[<p>Odată cu ascensiunea web-ului ca platformă de programare, în aplicațiile web au fost implementate o serie de metode de proiectare începând cu MVC, MVVM și ajungând la legături de date în UI, stocarea centralizată a stării și GraphQL. Dar ceea ce devine o tendință majoră în dezvoltarea software este abordarea centrată pe date de a descrie o aplicație.</p><h2>Aplicația sunt datele</h2><p>o aplicație provine dintr-un cod stocat ce poate fi privit drept configurația ei inițială. Insulele de cod programabil convertite în format executabil pot fi privite ca insule de date imuabile ce dau naștere la programul propriu-zis. Variabilele și zonele alocate de memorie pot fi privite ca insule mutabile de date ce sunt vizitate și transformate de semnalul care e aplicația ce rulează. Mai mult, o aplicație poate avea un set de date de configurare ce sunt stocate ca o configurație arborescentă care este de asemenea aproape statică în comparație cu programul ce rulează.<br /> Separarea și structurarea datelor mutabile și imuabile reprezintă cheia pentru construirea unei soluții durabile ce poate fi scalată și se adaptează în timp.</p><h2>Aplicația e business-ul</h2><p>Separarea datelor utile face parte din domeniul proiectării arhitecturii aplicațiilor curente. Pentru o aplicație pe platforma web, această arhitectură e modelul client-server cu împărțirea aplicației în UI, programul de pe server și centrul de date. De obicei, modelul de date de la ultima parte este transmis primelor două părți, ce sun structurate de cele mai multe ori ținând cont de metode de separare a preocupărilor precum MVC sau MVVM. Dar, după cum vom demonstra mai jos, adevărata aplicație e partea de procesare de pe server pe care o mai putem numi logica de business. De asemenea, canalul de comunicare dintre secțiunile client și server poate fi la distanță, local sau direct, ultimul caz descriind aplicațiile clasice precum cele desktop ce vor fi puternic ajutate de arhitectura propusă.</p><p><a href="/site-ro/wp-content/uploads/2023/06/3-data-models.png"><img class="aligncenter size-full wp-image-255" alt="3 data models" src="/site-ro/wp-content/uploads/2023/06/3-data-models.png" width="960" height="720" /></a></p><h2>Cele 3 modele de date</h2><p>Să presupunem că ambele canale de schimb de date de la UI la logica de business și de la logica de business la serviciul de persistență folosesc mesageria JSON. Fiecare mesaj JSON, fie trimis sau recepționat, poate avea mai multe tipuri de insule de date cum ar fi: conținut, validare și erori, parametrii interogării ș.a.m.d.. aceste structuri de date pot fi ajustate să corespundă schemei JSON ce descrie modelul de date al aplicației, a se vedea de exemplu <a title="Introduction to GraphQL" href="https://graphql.org/learn/" target="_blank">abordarea GraphQL</a>. Ce-ar fi dacă imediat după recepționarea unui mesaj sau chiar înainte de trimiterea lui aplicăm o transformare de date asupra insulelor sale de date, ceva mai complex sau neliniar precum o variantă XSLT pentru JSON sau mai simplu și liniar precum <a title="JUL Data Mapper" href="https://www.npmjs.com/package/jul-data-mapper" target="_blank">JUL Data Mapper</a>?<br /> Acum putem decupla modelul de date al logicii de business de celelalte două părți, interfața utilizator și nivelul de persistență și putem utiliza 3 scheme JSON pentru a descrie separat fiecare model.<br /> De remarcat faptul că o aplicație poate avea multiple perspective UI precum web, mobil, desktop, versiune publicitară, versiune plătită, etc.. se poate conecta de asemenea la mai multe servicii de persistență precum bază de date locală sau la distanță, API cloud, serverless, etc.. avansarea versiunii modelului de date al aplicației este, de fapt, ajustarea modelului de date al logicii sale de business și nu în mod necesar a celorlalte două părți ce pot avea o structură și o denumire a câmpurilor destul de diferită. Dacă privim diversele perspective ale UI și ale serviciului de stocare drept servicii externe, devine clar aspectul că funcționalitatea aplicației ar trebui să fie concentrată în partea sa de business. Aceasta este posibil acum prin separarea celor trei modele de date pe baza transformării datelor canalelor de date JSON, vom numi codul transformării ca driver al transformării de date (DTD).</p><h2>Flux de lucru</h2><p>Primul pas e identificarea corectă a părții logică de business a aplicației. Această parte a aplicației are o serie de trăsături comune dar nu obligatorii sau exclusive precum: abilitatea de a servi clienți multipli în același timp, rezidă pe partea de server, externalizarea serviciilor de persistență/stocare. Caracteristica definitorie este însă, procesarea informației critice de business, proces ce include luarea automată a deciziilor, validarea datelor, tratarea erorilor, întreținere, agregarea datelor, etc..<br /> Al doilea pas este formatarea tuturor cererilor și răspunsurilor ale fiecăreia din cele trei părți ale aplicației conform utilizării și semanticii respectivei părți, adică a schemei de date a acesteia. Ca exemplu, daca partea UI client trimite o cerere GET către logica de business, transmitem de obicei un ID al interogării și un hash cheie/valoare al parametrilor interogării vom folosi parametri interogare alfanumerici de forma &#8216;prop1.prop2.prop3 &#8216; și vom converti hash-ul într-un obiect structurat ce corespunde schemei de date a UI utilizând o metodă simplă cum ar fi aplicarea lui <a title="JUL - Limbajul UI JavaScript" href="/jul-limbajul-ui-javascript/">JUL</a>.ns() asupra fiecărei chei alfanumerice. Răspunsul JSON recepționat de la server va avea vectorul de articole și poate datele de validare sau de eroare structurate a se potrivi la schema de date a logicii de business și nu neapărat ca membri direcți ai obiectului rădăcină JSON.<br /> Pasul trei constă în a determina unde să inserăm codul DTD. Pentru partea client UI,, există de obicei un canal de date JSON la distanță către punctele de conectare server ca în arhitectura API REST. Vom aplica DTD-ul la punctul de conectare client al canalului de date, chiar înainte de apelarea metodei JSON.stringify() sau imediat după metoda JSON.parse() sau a hook-urilor/callback-urilor echivalente ale acestora.<br /> Logica de business e conectată la un serviciu de persistență/stocare via un modul ORM sau entitate-la-serviciu iar apoi, în multe cazuri, un canal de date la distanță ce poate să nu fie mesagerie JSON. ORM-ul trebuie privit ca parte a modelului de date al serviciului și trebuie să urmeze schema de date a serviciului de persistență. vom insera codul DTD ca hook-uri de transformare a datelor pe valorile argumentelor și pe valoarea răspuns/rezultat ale metodelor CRUD și altor metode ORM. Pentru cazurile î care canalul de schimb de date dintre partea de mijloc/secundă a aplicației și partea a treia a aplicației e JSON precum API web sau mesaje NoSQL, DTD-ul este situat la punctul de conectare al logicii de business cu canalul de date.<br /> Pasul patru este organizarea codului DTD în module. Pentru UI client există de regulă un singur modul DTD bidirecțional care va fi folosit pentru a transforma mesajele JSON trimise sau primite adică cererile și răspunsurile. La logica de business, există de regulă mai multe module DTD, câte unul pentru fiecare serviciu de persistență, unele dintre ele acționând doar asupra datelor JSON recepționate. În cazuri speciale, când la serviciul de persistență este disponibilă și procesare programabilă utilizator, se poate aplica un modul DTD la acel capăt al aplicației.<br /> Al cincilea pas este testarea end-to-end a aplicației cu modulele DTD introduse. Aceasta se face prin modificarea incrementală a structurii modelului de date al logicii de business apoi ajustând modulele DTD UI client și business-la-serviciu afectate. Ajustarea codului DTD ar trebui făcută prin configurare, lăsând intact codul principal al transformării de date ca în, de exemplu, JUL Data Mapper. Desigur, modificări structurale de date pot fi aplicate și la UI client și respectiv la serviciile de persistență, doar că într-un pas de testare separat.</p><h2>Tipuri de DTD și canale de date asociate</h2><p>Codul DTD poate fi rulat ca script, ca format binar sau chiar implementat în hardware. Toate aceste metode au în comun rularea transformării de date în memorie, lăsând configurabilă de către utilizator matricea de configurare a DTD sau codul său echivalent. Transformarea datelor în memorie poate fi aplicată pe orice structură arborescentă precum XML, DOM. SVG, JSON, etc. și e, în esență, limbaj-agnostică.<br /> Un model des întâlnit de utilizare a canalelor de date este transmisia folosind o infrastructură fizică sau livrarea de informație comprimată/criptată în software. La o privire mai atentă, în toate cazurile când avem un canal de date pentru a transmite informația relevantă, avem de asemenea cel puțin un conector de date hardware sau software ce acționează asupra informației relevante, în cazul cel mai simplu ca o matrice identitate.<br /> Vom utiliza reversul acestui model menționat anterior ca o regulă pentru a descrie arhitectura unei aplicații web: <em>într-o aplicație, oriunde este un conector de date adică un DTD, există un canal de date</em>.<br /> În concluzie, tipurile de canale de date în legătură cu un DTD sunt:</p><ul><li>Canale de date la distanță: când cele două capete ale canalului de date se află pe sisteme/infrastructuri diferite</li><li>Canale de date locale: când ambele capete ale canalului de date se află în același sistem</li><li>Canale de date virtuale/directe: când introducem un conector de date într-un schimb de date în memorie sau direct, altfel nealterat</li></ul><p>Merită menționat că, pe lângă DTD tipice unu-la-unu, pot exista DTD unu-la-mai-multe ce pot servi ca agregator de date pentru canale de date multiple. Totuși, în acest caz, va apărea problema sincronizării în timp a intrărilor de date, schimbând DTD-ul dintr-o transformare matricială liniară într-o mașină de stare. Ați putea încerca să utilizați mai multe DTD-uri unu-la-unu urmate de un modul de agregare a datelor.</p><h2>Aplicații</h2><p>Scenariul tipic pentru aplicarea arhitecturii propuse este inserarea DTD-urilor într-o aplicație web client-server. Fiind dată distincția clară dintre cele trei părți ale aplicației, beneficiile utilizării celor 3 modele de date sunt evidențiate anterior și se aplică aplicației instalate dar mai ales fazelor de dezvoltare inițială, mentenanță software și upgrade software a produsului.<br /> Paleta de aplicabilitate a unui DTD e totuși mai largă și include printre altele pe cele mobile, desktop, încapsulate, VR sau de limbaj natural. Aceasta se întâmplă deoarece partea UI/UX a acestor tipuri de aplicații poate fi privită ca o perspectivă utilizator pentru accesarea și manipularea părții de business a aplicației respective. De exemplu, dacă luăm o aplicație desktop ce se conectează la o bază de date serviciu local, legăturile de date în UI urmăresc structura și denumirile din modelul bazei de date printr-un cod ORM dacă însă inserăm un DTD direct înainte de ORM, nu numai că vom putea folosi un singur cod ORM dacă elevăm conexiunea la o bază de date producție, dar putem utiliza codul de business ce controlează operațiile crud pentru un UI diferit precum o aplicație mobilă remote.<br /> Deci, observați, cele 3 modele de date este un mod direct pentru dumneavoastră de a construi aplicații mai scalabile și mai universale.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/cele-3-modele-de-date/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Economia viitorului</title><link>http://constructorul-zonal.xhost.ro/economia-viitorului/</link> <comments>http://constructorul-zonal.xhost.ro/economia-viitorului/#comments</comments> <pubDate>Mon, 10 Oct 2022 09:04:29 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[ficțiune]]></category> <category><![CDATA[politică]]></category> <category><![CDATA[societate]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=54</guid> <description><![CDATA[Biosfera Pământului a avut câteva miliarde de ani pentru a se adapta și a supraviețui nenumăratelor fenomene naturale dar, e încă nepregătită pentru fenomenele artificiale pe care omenirea le-a adus în ultimele secole. Acestea sunt provocările globale curente precum poluarea, încălzirea globală, deșeurile industriale și casnice, rata de consumare a resurselor naturale etc. Ele nu [&#8230;]]]></description> <content:encoded><![CDATA[<p>Biosfera Pământului a avut câteva miliarde de ani pentru a se adapta și a supraviețui nenumăratelor fenomene naturale dar, e încă nepregătită pentru fenomenele artificiale pe care omenirea le-a adus în ultimele secole. Acestea sunt provocările globale curente precum poluarea, încălzirea globală, deșeurile industriale și casnice, rata de consumare a resurselor naturale etc.<br /> Ele nu ar trebui să pună vreo problemă pentru o rasă inteligentă ce acționează ca un super-organism.</p><h2>Provocări globale</h2><p>Efectele negative asupra mediului precum cele enumerate mai sus au o cauză comună: dorința umană pentru confort. Aceasta e parte a naturii umane pentru viitorul previzibil, deoarece orice ființă vie se va strădui să aibă o viață mai bună.<br /> Modelul destinație al unei rase evoluate are câteva trăsături cunoscute: abilitatea de a se adapta, abilitatea de a evolua, a acționa ca o singură voință când e necesar, a gândi ca o singură minte pentru o cauză comună, să facă față mediului înconjurător dar să păstreze echilibrul între natură, necesități și interese.<br /> Primii pași spre un astfel de super-organism sunt deja făcuți: comunicații globale strânse și răspândirea globală a ideilor/gândirii. Următorii pași predictibili sunt: educația globală standard și conștientizarea globală a problemelor omenirii.<br /> Provocările noastre globale sunt, de fapt, îndeplinirea corectă a acestor pași evoluționari pozitivi până la momentul în care a avea grijă de planetă și de locuitorii ei înseamnă a avea grijă de propria casă.</p><h2>Salt spațial</h2><p>S-ar putea crede că pasul următor în evoluția umană este explorarea și colonizarea spațială. În timp ce acest pas pare rezonabil, adnotarea ca &#8220;următor &#8221; ar putea să nu aibă suficientă acuratețe.<br /> În prima etapă a colonizării chiar și a sistemului nostru solar, trebuie să avem acasă o bază unde ne putem întoarce sau de unde putem obține ajutor, în marea majoritate a cazurilor în care misiunile la mari distanțe vor servi mai degrabă la a învăța decât la a avea succes.<br /> Ce-ar fi dacă pasul nostru următor este un salt spațial în apropiere menit să pună în siguranță baza de acasă, adică să salveze biosfera Pământului?<br /> Unele obiective inițiale ambițioase ar fi, de exemplu, migrarea 15% din producția echivalentă de energie electrică de la suprafață și 10% din industria grea de prelucrare a metalelor în spațiul extern, lângă planetă. În combinație cu planul în curs pentru o economie verde, aceasta ar duce la o reducere procentuală semnificativă a disipării termice și a reziduulor industriale, într-o perioadă mult mai scurtă de timp.</p><h2>Principiul conservării locale</h2><p>Miracolul vieții pe Pământ a fost predeterminat de o serie de factori cosmici și geologici, cum ar fi: forma orbitei planetare, perioada sa de rotație, viteza de rotație în jurul axei, unghiul de înclinare axial, temperatura miezului și a scoarței terestre, dimensiunea și compoziția atmosferei sale, orientarea polilor magnetici și puterea sa de ecranare electromagnetică ș.a.m.d.<br /> Este de așteptat ca, pentru viitoarele milenii sau mai mult, rasa umană nu va controla complexitatea factorilor menționați anterior.<br /> Astfel, poate fi valabil următorul principiu de conservare a masei și energiei locale:<br /> <em>masa totală a planetei și a corpurilor ce orbitează în jurul său și energia termică absorbită de către planetă și atmosfera sa trebuie păstrate la valori constante, conform celor ce survin în mod natural.</em><br /> Printre alte lucruri, aceasta implică să nu aducem corpuri din spațiu situate în afara câmpului gravitațional al Pământului, ci mai degrabă să le folosim pe cele deja capturate în acesta și, de asemenea, nu creștem disiparea termică de la suprafața planetei cu energia produsă în spațiul extern, ci mai degrabă înlocuim o parte din producția terestră cu cea din urmă.<br /> În acest context, toate planurile de a face mediul înconjurător mai sănătos și verde rămân foarte valabile.</p><h2>Proiectul Zenyth</h2><p>La începutul mileniului 3, omenirea a demarat construirea a trei stații spațiale ce se rotesc în jurul Pământului. Asamblate din vehicule spațiale lansate anterior, acestea sunt un precursor al inelului industrial spațial ce va furniza producția planetară de înalt nivel în mileniul 4.<br /> Stațiile sunt la 120 grade depărtare una de alta și descriu o orbită ecuatorială de 8 ore de la vest la est. Aceasta rezultă într-o viteză pozițională dublă față de viteza de rotație a suprafeței Terrei, adică mai puțin de 1 km/s .<br /> Durata dus-întors a semnalelor electromagnetice între Pământ și o stație este de sub 0,1 s, ceea ce face posibile operațiunile cu stația în mod cvasi-instantaneu.<br /> Două stații spațiale au rol de a livra energie suplimentară planetei, iar cealaltă se ocupă cu mineritul spațial și construcția de facilități spațiale.<br /> Fiecare stație e capabilă să producă energie și are robotizare cel puțin la nivel de bază.<br /> Stațiile au echipaje foarte mici alocate pe o perioadă de doi ani cu concedii aprobate individual. Marea majoritate a operațiunilor sunt executate prin <a title="teleprezență" href="#telepresence">teleprezență</a> de către un numeros personal specializat situat pe Pământ . <em id="telepresence">teleprezența este procesul de a conecta intrările și ieșirile de tip senzorial și volitiv ale omului la o combinație de acționări, robotizări și operațiuni asistate de AI, într-un cadru de feedback perceptual rapid și control automat pe micro-durate.</em><br /> Chiar din faza inițială, comunicarea,  coordonarea și colaborarea între cele trei stații spațiale sunt atât  de dorit, cât și necesare.</p><h2>Artemis</h2><p>Construită de Parteneriatul Pacificului ce include printre alții, SUA, Japonia, Coreea și Australia, această stație spațială transferă energia solară către Terra folosind tehnologia laserului roșu.<br /> Utilizând o serie de oglinzi concave și concentratori de lumină, stația produce câteva fascicule focalizate care ating atmosfera Pământului cu raza de sub 100 m și intensitatea în infraroșu de până la 30 de ori celei a radiației solare. Fasciculele sunt intermitente, cu activare timp de 0,3 s și dezactivare timp de 0,2 s .<br /> Între tropice, împrăștiate peste tot în jurul globului, lângă țărm sau pe sol, se află aproape 200 de uzine solare, pregătite  să recepționeze și să utilizeze fasciculele concentrate  de lumină. O uzină solară e un câmp de oglinzi focalizatoare ajustabile cu un strat de asistență de panouri solare dedesubt ce se întinde pe o arie de 1,732 x 1,0 km pătrați de la vest la est.<br /> În funcție de condițiile atmosferice, stația spațială alege și se sincronizează cu o uzină solară și începe transmiterea rafalelor de fascicule pentru aproximativ 5 minute, cât timp deviația longitudinală la azimut rămâne sub 1,5 grade. Orice perturbare pe calea de transmitere sau la locația de recepție face ca emisia să fie oprită.<br /> Sistemul oglinzilor de recepție e capabil să focalizeze fasciculele spre un număr de acumulatoare metalo-ceramice verticale de căldură sau, în cazul optim, spre un singur punct de focalizare ce se poate comporta ca un activator de micro-reacție nucleară. Uzina folosește căldura pentru a descompune apa în oxigen și hidrogen, ultimul fiind colectat și lichefiat treptat cu micro-pompe în mici celule tubulare de fibră de sticlă. Fiecare uzină are o matrice ajutătoare de acumulatori electrici pentru operare și mentenanță.<br /> Ea are de asemenea control de la distanță și monitorizare 24/7, iar un terț poate încărca o cantitate de hidrogen de la uzină după primirea unui cod de deblocare de la furnizorul de energie.</p><p><em>Rezumat</em></p><p>După trei ore de călătorie, pasagerii zborului matinal regulat de la Atlanta la Johannesburg sunt treziți de o voce: &#8220;Bună dimineața doamnelor și domnilor și scuze pentru deranj. Suntem deasupra coastei de nord-est a Braziliei, dar vom face un mic ocol de jumătate de oră deoarece o uzină solară de sub noi tocmai își începe activitatea de recepție. Vă rog să vă conectați la display-urile VR dacă doriți să vă bucurați de spectacol. Sunt căpitanul, mulțumesc. &#8220;.<br /> Ei pot vedea prin dispozitivele VR ceva ce seamănă cu o floare de lotus privită de la mare distanță. În câteva momente, lotusul își aprinde petalele roșii ce se întind acum ca niște raze pe distanță lungă, semnalând începerea activității intense a uzinei solare. Brusc, un fulger vertical roși străbate văzduhul direct spre uzină și continuă înroșind cerul și făcând ca uzina să dispară din priviri. După un timp, ochii se acomodează cu ceea ce pare acum un bombardament laser de la o navă extraterestră.<br /> Trec câteva minute lungi, rafalele se opresc la fel de brusc cum au pornit și micul lotus apare neafectat, spre marea uimire a privitorilor.<br /> &#8220;Cum se pot asigura că nu lovesc un avion sau, mai rău, o casă de pe țărm? &#8220;Întreabă o tânără, gândind cu voce tare. &#8220;Stimată domnișoară&#8221; răspunde un domn mai din față &#8220;oamenii de știință au conceput pentru stația spațială, ceea ce numim un tun logaritmic, a cărui formă permite o precizie de 100 m a razei fasciculului la sol, ca și cum s-ar folosi o conductă reflectoare de 1 cm cu lungimea de 1,4 km. &#8221;<br /> Vocea căpitanului se aude din nou: &#8220;Oameni buni, secundul meu a observat că putem fi martori la un fenomen foarte rar: curcubeul vertical. Vom coborî 3000 de picioare la nivelul norilor, iar ferestrele avionului vor deveni transparente pentru vedere exterioară. &#8220;.<br /> Ultimele urme de somn dispar de pe fețele copiilor și ale adulților, în timp ce se grăbesc spre partea dreaptă a avionului pentru a privi pe fereastră.<br /> Pe când avionul își continuă neperturbat voiajul peste Atlantic, în spate, la depărtare, pare că cineva a pictat o bandă colorată pe un perete de pe cer, strălucind în jos în violet deschis, galben-oranj și roșu palid.</p><h2>Lyna</h2><p>Construită de Convenția Pan-Asiatică, ce include printre alții China, India, Rusia și Iran, aceasta folosește tehnologia microundelor pentru a converti și a transmite energia solară către receptori plutitori din stratosfera Pământului.<br /> Stația convertește radiația solară de înaltă energie în electricitate, iar apoi emite rafale de microunde focalizate spre ținte în stratosfera inferioară<br /> Acestea sunt mari baloane elipsoidale cu dimensiunea axelor de 1,2 km x 0,6 km, capabile să atingă și să se mențină cu ușurință la altitudini peste nivelul norilor.<br /> Construit din fibră textilă impregnată cu cauciuc natural ignifug, un balon are peste 90% camere cu aer cald și un mic număr de camere cu heliu, astfel încât, atunci când aerul se răcește, balonul coboară încet spre sol.<br /> În nacelă, sunt acumulatori și circuite electrice ce produc mici descărcări de înaltă-tensiune ce păstrează aerul fierbinte și îl ionizează treptat.<br /> Pe partea superioară a balonului se află o combinație de receptoare de microunde și panouri solare. Receptoarele convertesc rafalele de microunde de la stația spațială direct în descărcări de înaltă-tensiune, mărind substanțial rata de ionizare.<br /> Eficiența descărcărilor poate fi sporită producându-le în mici celule în care aerul trece presurizat la câteva atmosfere.<br /> Din cele aproape 150 baloane energetice, o treime din ele ce sunt complet încărcate sunt aterizate și sunt aduse la cel mai apropiat oraș, unde acestea funcționează ca o baterie uriașă, convertind gradual ionizarea gazului de aer în electricitate, prin utilizarea unui convertor avansat de energie din nacelă. O terță parte poate prelua balonul, dar electricitatea poate fi accesată după primirea unui cod de deblocare de la furnizorul de energie.<br /> Fiecare balon are un transmițător activ permanent ce transmite locația sa exactă și statistici în timp real.</p><p><em>Rezumat</em></p><p>Soarele răsare peste unul din porturile din sudul Okinawa-ei, unde echipajele a două mici fregate se pregătesc rapid pentru plecarea pe mare. &#8220;Domnilor &#8220;, spune Yoshi Nakamuro,  căpitanul unuia dintre cele două vase, &#8220;astăzi mergem să vânăm o e-balenă, cunoscută de asemenea și ca balon energetic.  Dacă reușim, veți avea mai puține griji financiare pentru următoarele trei luni. &#8221;<br /> O oră mai târziu, pe coasta de nord a Filipinelor, douăsprezece vase de pescuit electrice se îmbarcă pentru aceeași misiune. Cu vântul suflând ușor dinspre sud în pânzele lor suplimentare, sunt încrezători că vor atinge până la apusul soarelui punctul de aterizare al balonului în Pacific, de două ori mai aproape față de partea japoneză.<br /> Ziua se apropie de asfințit, când marinarii filipinezi încep să vadă de la mare distanță imensul monstru coborând încet prin aer.<br /> Japonezii sunt cu aproape 20 minute în urmă, dar Căpitanul Nakamuro îi comunică celeilalte fregate: &#8220;Radarul nostru arată că balonul acesta aterizează cu 10 m/s, dublu față de normal. Aceasta va crea un val de izbire de 5 m înălțime pe o rază de 3 km. Recomand reducerea vitezei și alinierea navelor pentru impact. &#8221;<br /> Cinci dintre vasele de pescuit sunt prinse prea aproape de micul tsunami și suferă pagube, forțându-le pe celelalte șapte să le acorde ajutor. Apropiindu-se din sens opus, prima fregată lansează cablul de tractare și de date ghidat de o torpilă de cuplare. De îndată ce cablul este cuplat la nacela balonului, ei introduc un cod de preluare și balonul devine custodie definitivă a echipajului.<br /> Acum începe drumul plin de provocări înapoi spre casă unde, după o scurtă ceremonie, vor transfera autorităților locale custodia balonului.</p><h2>Hera</h2><p>Construită de Forumul Economic Mediteranean. ce include printre alții UE, UK, Liga Arabă și Confederația Africană pentru Progres, stația folosește tehnologia avansată în robotică pentru construcțiile spațiale și aeronautice și pentru mineritul corpurilor spațiale apropiate precum asteroizi sau meteoriți.<br /> Ea livrează anumite minerale și metale rare către planetă prin intermediul nou construitelor avioane stratosferice și primește combustibil de retro-motoare pentru misiunile sale spațiale de proximitate.<br /> Majoritatea misiunilor spațiale constă în aducerea micilor fragmente pentru minerit în orbită sincronă cu Terra, preferabil apropiată de cea a stației.<br /> Cu cât mai departe de Pământ e corpul din spațiu, cu atât mai puțină putere de retro-motoare e necesară pentru a-l devia de la traiectoria sa.<br /> Stația spațială acceptă comenzi de construcție și de minerit pe bază de contracte comerciale.</p><p><em>Rezumat</em></p><p>Pare să se lase o noapte senină și liniștită în emisfera nordică, dar sus pe cer stația derulează o activitate în ritm alert. O mică navă se lansează de pe stație și pornește rapid către atmosferă într-o traiectorie orbitală descendentă. Are șase scuturi romboidale pe fețele celor trei direcții ortogonale, cuplate cu șase retro-motoare sub fiecare scut.<br /> La intrarea în atmosferă, nava argintie se înroșește din cauza căldurii de frecare, când, în mod surprinzător, își schimbă gradual forma într-un avion supersonic tip aripă-V, ce își continuă rapid drumul spre destinație.<br /> La sol, în primitorul oraș Abu Dhabi, o echipă de cercetători europeni și de reprezentanți locali supraveghează atent sosirea avionului stratosferic auto-pilotat.<br /> În holul de recepție al agenției de coordonare a zborului se aude un ropot de aplauze, în tip ce își face apariția presa și se pregătește să ia interviu echipelor oaspete și locală.<br /> &#8220;Profesor Kroner &#8220;, spune Kim Min Hae, unul dintre reporteri, &#8220;Felicitări pentru succesul realizărilor dvs. din industria aero-spațială. Dar observatoarele noastre astronomice au descoperit începerea construirii unui port spațial la 50 km est de stație. Doriți să comentați pe acest subiect? &#8220;.<br /> După ce zâmbește scurt, Profesorul Peter Kroner replică: &#8220;Este un efort comun al agențiilor spațiale americană, asiatică și europeană. Este în etapa sa timpurie deoarece încă monitorizăm progresul tehnologiilor motorului cu fuziune, ecranării electromagnetice și armăturii poli-aliaj. &#8220;.  reportera adaugă: &#8220;Am auzit că sunt deja alese clasificarea și numele pentru prima navă construită acolo. &#8220;, iar liderul echipei științifice răspunde: &#8220;Ea nu are încă un nume oficial, dar colegilor noștri internaționali și nouă ne place să o numim: Enterprise. &#8220;.</p><h2>Conectați la viitor</h2><p>Este o după-amiază însorită în orașul perpetuu Mumbai, India, în care elevii din anul al doilea de la Liceul Central se pregătesc pentru lecția de două ore de astronomie. &#8220;Astăzi vom face o vizită pe stația spațială al cărei membru este și țara noastră. Vă rog să vă echipați în costumele VR și să vă alăturați grupului virtual de vizitare. &#8220;, spune profesorul.<br /> Peste câteva momente peisajul se schimbă și, într-o cabină spațioasă plină de monitoare, sunt întâmpinați de un bărbat jovial de vârstă medie îmbrăcat în uniformă de gală. &#8220;Bună ziua copii. Sunt Comandorul Alexey Markov și, în numele Căpitanului Lee Po Fang, vă spun bun venit pe stația noastră spațială internațională. În prima parte a vizitei voastre, veți putea admira faimoasa panoramă de monitorizare a baloanelor, unde puteți vedea baloanele noastre energetice colorate în alb de la cele ridicate recent la oranj intens pentru cele complet încărcate și, chiar și albastru pentru cele câteva ce tocmai coboară. În ultima parte, cei care au optat dintre voi, vor face o mică plimbare spațială împreună cu inginerul nostru șef și un membru al echipei sale spre brațul mobil spațial de pe platforma de andocare a stației. Rețineți doar o simplă regulă pentru orice viitor cosmonaut: în spațiu nu există &#8216;cu susul în jos&#8217;. Ca temă, vă dau task-ul ușor de a calcula masa totală pentru o bulă sferică de aer cu raza de 300 m, dându-se densitatea nominală a aerului de 1,204 kg pe metru cub și 0,5236 ca raportul volumelor între o sferă și un cub de aceeași dimensiune. Cei dintre voi care obțineți rezultatul corect, nu vă temeți dragii mei, deoarece conform legii lui Arhimede, în atmosferă, bula noastră zburătoare e ușoară ca o pasăre. &#8220;.<br /> În timp ce uimitoarea lecție de astronomie ia sfârșit, pentru unii dintre elevi, aceasta va marca un punct de cotitură decisiv în cariera lor viitoare de a deveni specialiști internaționali în operațiunile spațiale ale rasei umane.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/economia-viitorului/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Dreptul la solidaritate</title><link>http://constructorul-zonal.xhost.ro/dreptul-la-solidaritate/</link> <comments>http://constructorul-zonal.xhost.ro/dreptul-la-solidaritate/#comments</comments> <pubDate>Wed, 10 Oct 2018 18:39:57 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[politică]]></category> <category><![CDATA[societate]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=48</guid> <description><![CDATA[Așa cum e descris în articolul &#8220;Despre economia viitorului&#8221;, economia globală se află în fața unei schimbări majore către o construcție la scală mare a capacităților spațiale. Pentru a putea dezvolta o astfel de industrie, sunt necesare nu doar eforturile conjugate a mai multor țări sau uniuni politice, dar și resursa individuală a expertizei și [&#8230;]]]></description> <content:encoded><![CDATA[<p>Așa cum e descris în articolul &#8220;Despre economia viitorului&#8221;, economia globală se află în fața unei schimbări majore către o construcție la scală mare a capacităților spațiale. Pentru a putea dezvolta o astfel de industrie, sunt necesare nu doar eforturile conjugate a mai multor țări sau uniuni politice, dar și resursa individuală a expertizei și creativității umane este critică.<br /> Dar, unde veți găsi resursa umană adecvată atunci când provocările planetare devin copleșitoare și escaladează cu trecerea timpului?</p><h2>În unire stă puterea</h2><p>Este știut că, atunci când avem de rezolvat o sarcină majoră, o echipă este preferabilă unui singur om. Aceasta se aplică și mai mult dacă sarcina presupune o activitate calificată sau know-how tehnologic. Dar, dacă discutăm despre domeniul cercetării, efectele de a fi mulți, deși mai subtile, sunt încă și mai hotărâtoare.<br /> Să ne imaginăm că, pentru munca necesară unei descoperiri importante în tehnologia fuziunii la rece, o țară dezvoltată poate furniza 100 de specialiști pentru o anumită perioadă de timp, să spunem 30 de ani. Dacă aceeași țară ar putea oferi pentru aceeași sarcină 1000 de specialiști, nu doar viteza estimată a cercetării va crește de 10 ori, dar și probabilitatea ca unul dintre ei să fie viitorul Einstein va crește corespunzător. Acesta este desigur un scenariu simplificat, dar ați înțeles ideea.</p><h2>Mawi</h2><p>În Africa Centrală deșertul se învecinează cu o savană și cu albia unui râu ce se umple cu apă în sezonul ploios. Locuitorii unui mic sat de lângă râu își mută cirezile de vite cu fiecare schimbare de anotimp, căutând pășunile cele mai bune pentru a-și asigura traiul de zi cu zi.<br /> Încă de când era un băiat de zece ani, Mawi a învățat de la bunicul său că trebuie să trăim în armonie cu natura, pentru fiecare lucru ce luăm trebuie să dăm ceva înapoi. Bunicul spunea de asemenea că există forțe nevăzute ce unesc toate lucrurile împreună, iar o persoană ar trebui să țină seama de ele și să respecte aceste forțe. Dintre ceilalți copii, Mawi era primul ce învățase să citească schimbarea vremii, să găsească indiciile unui sol cu apă subterană și învățase chiar și câteva stele de pe cer ce ajută călătorul care merge într-un loc îndepărtat.<br /> Toți sătenii respectau un cod strict al onorării tradițiilor și aduceau laudă forțelor naturii care le permiteau o existență neîntreruptă de atâtea generații. Dar Mawi simțea că forțele nevăzute sunt menite a fi cunoscute de către om și că el ar putea ajunge la o înțelegere mai profundă a ceea ce considerau ceilalți săteni ca fiind de neschimbat.<br /> Într-o zi un grup de străini purtând haine lungi și ochelari de soare a ajuns în sat. Aceștia i-au adunat pe copii pentru a juca un concurs de istețime folosind niște dispozitive micuțe ce vorbesc și arată diverse imagini când le ții în mână. Ei au observat că Mawi învăța foarte repede și avea un mod natural de a interacționa cu dispozitivul și au decis să i-l dea cadou. Au vorbit cu bătrânii satului și s-au oferit să se întoarcă peste doi ani cu o propunere de bursă școlară pentru Mawi pe măsură ce acesta progresează cu învățătura.<br /> Douăzeci și doi de ani mai târziu, în America de Nord la Institutule de Fizică și Astronomie, profesorul Eric Schuman, președinte al Academiei de Știință, deschidea conferința bienală despre Realizări și Descoperire cu un discurs: &#8220;Ne-am reunit aici pentru a saluta pasul decisiv înainte în punerea bazelor pentru o economie soațială sustenabilă, făcut posibil de descoperirea uimitoare a undelor anti-gravitaționale de către excepționalul nostru coleg Dr. Mawi Erbassa. Transportul spațial eficient și producția orbitală în sistemele noastre planetare pot deveni în sfârșit o realitate curentă &hellip;&#8221;</p><h2>Necesitate sau evoluție?</h2><p>Așa cum se vede în <a href="https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs" target="_blank">piramida nevoilor a lui Maslow</a>, un individ este condus de nevoi de bază dar și de ordin mai înalt, atunci când vine vorba de descrierea comportamentului uman. Dar, în timp ce nevoile individuale pot fi identificate cu destulă acuratețe, nevoile societății formate din multipli indivizi constituie baza a nesfârșite dezbateri politice și filozofice de-a lungul istoriei.<br /> Într-o epocă în care comunicarea între oameni este cvasi-instantanee, societatea este mult mai integrată în ce privește partajarea ideilor, schimbul de opinii și multe alte activități legate de gândire. Rasa umană ar trebui privită ca un super-organism ale cărui nevoi e necesar să fie identificate corect și chiar anticipate. O umbrelă sub care toate aceste nevoi pot fi adunate este evoluția rasei umane. Istoria vieții a arătat că dacă o specie e să reușească în demersurile sale, acesta trebuie să reușească în evoluția sa. Dacă vrem să identificăm necesitățile rasei umane, trebuie să-i anticipăm traiectoria, cercetând în special evoluția sa viitoare. Ca și în piramida nevoilor, rasa întreaga va fi afectată în evoluția sa dacă nevoile de baza ale tuturor oamenilor vor rămâne nesatisfăcute.</p><h2>Dreptul la solidaritate</h2><p>Definiția dreptului la solidaritate este:<br /> <em>Fiecare om trebuie să aibă acces la hrană și adăpost.</em></p><h2>Implementare</h2><p>Fiecare țara sau uniune politică va construi o serie de locuințe modulare grupate în arii denumite campusuri ale solidarității.<br /> Operarea acestor arii va fi asigurată de către armată sau de către o organizație legală echivalentă cu un cod strict de conduită și o bună performanță operațională în cazul în care nu e constituită vreo armată. Finanțarea și necesarul de materiale ale campusurilor vor fi asigurate de către guvern sau de către o organizație legală echivalentă ordonatoare de buget în cazul în care nu este constituit vreun guvern. Supervizarea și responsabilitatea politică pentru buna stare a campusurilor va fi asigurată de către parlament sau o organizație legală echivalentă reprezentativă în cazul în care nu e constituit vreun parlament.<br /> Orice persoană cu răspundere de sine poate solicita acces la campus pentru o anumită perioadă de timp începând cu o lună, ex. 1, 3, 6, 12 luni, și reînnoi cererea cu câteva zile înainte de expirare. Copiii sub 2 ani sunt admiși împreună cu mama lor dacă aceasta este prezentă. Pentru toți ceilalți copii, orice persoană ce solicită o perioadă de acces și este un tutore legal al acestor copii, va fi de acord ca statul prin instituțiile sale se va ocupa de hrana, adăpostul și educația lor pentru aceeași perioadă de timp.<br /> În interiorul campusului se aplică domnia legii, drepturile omului și dreptul la solidaritate. Doar funcțiile de hrană și adăpost vor fi îndeplinite de către campus, orice alte funcții de susținere periclitându-i până la urmă existența. Accesul va fi permis pentru ore de adăpost precum 6 ore timp de dormit, vreme rea precum sub -20&deg;C sau catastrofe naturale decretate de lege. Accesul va fi permis de asemenea pentru trei perioade scurte de timp când hrana este distribuită și consumată. Orice bunuri personale sunt reținute la intrare și returnate la ieșire. O persoană poate ieși oricând din campus dar va fi primită doar când începe o perioadă de adăpost sau de masă. De asemenea, la sfârșitul fiecărei perioade campusul va fi evacuat și se vor face sarcini de mentenanță.<br /> Campusul consistă în unități modulare de locuit pentru o persoană fiecare și unități de service precum toalete, birouri de personal, unități energetice și de comunicații. Fiecare unitate are un decor minimal, este conectată la o sursă de încălzire și de energie, are capacitate de supraveghere și poate fi inspectată de personalul operațional. Unei persoane îi va fi dată o unitate de locuit aleatoare ce diferă de fiecare dată când începe o perioadă de hrană sau de adăpost. Hrana va fi livrată și consumată în interiorul acestor unități de locuit. Mai multe perioade pot fi lipite între ele din motive de eficiență eliminând evacuările intermediare, dar păstrând cel puțin două perioade zilnice de mentenanță de 4 ore fiecare. Circulația și accesul în interiorul campusului vor fi limitate și supravegheate. Toaletele sunt module de o persoană cu seturi de spălare incluse. În afară de anumite restricții administrative, nici o obligație nu va fi creată pentru persoanele ce accesează campusul.</p><h2>Consecințe</h2><p>Eliberarea individului de necesitatea de a rezolva două dintre cele mai de bază nevoi va contribui dramatic la evoluția rasei. Nevoilor de nivel mai înalt li se va acorda mai multă atenție, iar capacitatea de rezolvare a problemelor a comunității globale va crește de zece ori. De asemenea, se pun bazele pentru o lume nai civilizată și mai educată odată cu integrarea în mințile oamenilor a dreptului la solidaritate. Oamenii vor considera în scurt timp o obișnuință ca spălatul pe mâini să muncească într-o mică fracțiune și pentru nevoia comunității care în schimb le va asigura accesul la dreptul la solidaritate. Merită menționat și că drepturi morale precum demnitatea umană și respectul de sine vor fi puternic întărite.<br /> Vectorii de evoluție ai rasei umane pot fi schimbați de diverse evenimente în moduri nu neapărat pozitive pentru viitor. De ce să nu-i schimbăm într-un mod controlat cu o contribuție pozitivă decisivă pentru ființa umană?</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/dreptul-la-solidaritate/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Concepte avansate JUL &#8211; partea a 2-a</title><link>http://constructorul-zonal.xhost.ro/concepte-avansate-jul-partea-a-2-a/</link> <comments>http://constructorul-zonal.xhost.ro/concepte-avansate-jul-partea-a-2-a/#comments</comments> <pubDate>Fri, 03 Nov 2017 17:04:29 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JUL]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=47</guid> <description><![CDATA[jÎn articolul anterior am văzut că JUL poate genera arbori de componente și poate gestiona lucrul cu obiecte de configurare. Dar JUL are nai mulți ași în mânecă atunci când se discută de spațiile de nume de configurare. Spații de nume &#8211; utilitate și relativitate Un spațiu de nume în JavaScript e un obiect global [&#8230;]]]></description> <content:encoded><![CDATA[<p>jÎn <a title="Concepte avansate JUL - partea 1" href="/concepte-avansate-jul-partea-1/">articolul anterior </a> am văzut că JUL poate genera arbori de componente și poate gestiona lucrul cu obiecte de configurare.<br /> Dar JUL are nai mulți ași în mânecă atunci când se discută de spațiile de nume de configurare.</p><h3>Spații de nume &#8211; utilitate și relativitate</h3><p>Un spațiu de nume în JavaScript e un obiect global care stochează diverse alte obiecte și funcții. Istoric, spațiile numea au fost folosite pentru a permite existența non-conflict a mai multor biblioteci de unelte JavaScript în același mediu runtime (pagină web). Prin folosirea spațiilor de nume, autorii au obținut nu doar utilizarea clară bon-conflictuală a scopului global, dar și organizarea structurală inerentă a utilitarelor lor. Mai recent, rolul spațiilor de nume de a încărca și de a utiliza bibliotecile JavaScript într-un mediu de lucru a fost luat de către module, exemplul cel mai relevant fiind CommonJS în Node. Unii spun că, odată cu consacrarea modelului modulelor, spațiile de nume sunt învechite, dar spații de nume înseamnă structură, iar structura nu e niciodată învechită.<br /> JUL oferă o serie de utilitare pentru lucrul cu spații de nume: JUL.ns(), JUL.get(), JUL.Instance().<br /> Dacă doriți să creați un obiect într-un spațiu de nume dat, chiar dacă spațiul de nume nu există, puteți folosi JUL.ns().<br /> Dacă doriți să regăsiți un obiect de la calea sa în scopul global (succesiunea de nume de proprietăți separate prin punct), puteți folosi JUL.get().</p><pre class="brush:js">// crearea unui spațiu de nume
var oNS = JUL.ns('@.non-standard.tools &amp; libs');
JUL.apply(oNS, {
	setting1: 'Custom NS',
	setting2: ['first', 'second', 'third'],
	method1: function() {
		console.log('Method 1');
	}
});
// obținerea unui membru al spațiului de nume
console.log(JUL.get('@.non-standard.tools &amp; libs.setting2.2'));</pre><p>Dar spațiile de nume nu sunt neapărat legate de scopul global (absolute), ele putând fi folosite relativ la un scop local.<br /> Cea mai puternică utilizare în scop a spațiilor de nume este dată de clasa JUL.Instance(), care face toate operațiile de spațiu de nume, JUL.get() sau JUL.ns(), relative la un spațiu de nume de bază (rădăcină). Pentru orice parser-i și referințe create de JUL, se poate folosi utilitarul JUL.getInstance() pentru a obține instanța originală ce a creat obiectul.</p><pre class="brush:js">var sNS = '#.non-standard.~tools~';
var oLocal = {};
// crearea unui spațiu de nume relativ
var oNS = JUL.ns(sNS, {}, oLocal);
JUL.apply(oNS, {
	property1: {x: 5, y: 3},
	property2: /^new/i,
	'a-method': function() {
		console.log('A method');
	}
});
// obținerea unui membru al spațiului de nume relativ
var fCall = JUL.get(sNS + '.a-method', oLocal);
fCall();
// crearea unei instanțe JUL atașată la un spațiu de nume
var jul = new JUL.Instance({nsRoot: oNS});
console.log(jul.get('property1.x'));
// obținerea unei instanțe implicite
var oParser = new JUL.UI.Parser({
	nsRoot: oNS,
	yopDown: true,
	useTags: true
});
console.log(JUL.getInstance(oParser).get('property2'));</pre><h3>Preluarea și punerea în scop a metodelor</h3><p>Mai multe utilitare JUL precum JUL.UI.factory() sau JUL.UI.createDom() acceptă o cale punctată acolo unde se așteaptă o funcție / un callback. Intern, această cale e rezolvată la obiectul concret utilizând JUL.get().</p><pre class="brush:js">var oTree = {
	tag: 'div',
	css: 'wrapper',
	children: [
		{tag: 'input', id: 'input-name', value: 'A text', listeners: {change: 'NS.lib.defaultChange'}},
		{tag: 'button', id: 'button-go', html: 'Go', listeners: {click: 'NS.lib.defaultClick'}}
	]
};
var oParser = new JUL.UI.Parser({
	defaultClass: 'html',
	customFactory: 'JUL.UI.createDom',
	topDpwm: true,
	useTags: true
});
var oNS = JUL.ns('NS.lib');
JUL.apply(oNS, {
	defaultClick: function() {
		console.log('Button clicked');
	},
	defaultChange: function() {
		console.log('Text changed');
	}
});
oParser.create(oTree, null, window.document.body);</pre><p>Aceasta îi permite unui obiect de configurare să stocheze callback-uri nerezolvate la momentul încărcării lor. Dar, dacă vreți ca aceste callback-uri să fie apelate într-un scop dat, puteți utiliza JUL.makeCaller() pentru a crea un wrapper cu cache și cu scop fixat pentru o anumită funcție (similar la ES5 Function.prototype.bind()). Când se atașează listener-i la un element DOM, JUL.UI.createDom() face legarea automat dacă furnizați o proprietate scope în obiectul de configurare listeners.</p><pre class="brush:js">var oTree = {
	tag: 'div',
	css: 'wrapper',
	children: [
		{tag: 'input', id: 'input-name', value: 'A text', listeners: {scope: 'NS.lib', change: 'NS.lib.defaultChange'}},
		{tag: 'button', id: 'button-go', html: 'Go', listeners: {scope: 'NS.lib', click: 'NS.lib.defaultClick'}}
	]
};
var oParser = new JUL.UI.Parser({
	defaultClass: 'html',
	customFactory: 'JUL.UI.createDom',
	topDpwm: true,
	useTags: true
});
var oNS = JUL.ns('NS.lib');
JUL.apply(oNS, {
	clickMsg: 'Button clicked',
	changeMsg: 'Text changed',
	defaultClick: function() {
		console.log(this.clickMsg);
	},
	defaultChange: function() {
		console.log(this.changeMsg);
	}
});
oParser.create(oTree, null, window.document.body);</pre><h3>Escaping cale punctată</h3><p>La utilizarea șirului de caractere cale spațiu de nume (cale punctată) pentru preluarea unui obiect, există o serie de aspecte la care trebuie avut grijă.<br /> Fiecare segment descrie un șir proprietate de obiect, astfel că poate avea un format mult mai larg decât șirurile nume de variabilă sau indecși de vector. Va fi folosit un singur separator (aducă un punct) pentru a separa două segmente ale căii, iar calea poate fi folosită pentru a traversa orice obiecte de configurare, inclusiv vectori.<br /> Pentru a acoperi toate cazurile de utilizare, JUL oferă o sintaxă escape pentru o cale punctată, în care toate punctele prezente într-un șir proprietate sunt precedate de un backslash atunci când sunt utilizate înăuntrul căii.<br /> Toate rutinele JUL care folosesc căi punctate, cum ar fi JUL.ns() sau JUL.get(), suportă această sintaxă.</p><pre class="brush:js">var oNS = JUL.ns('NS.dotted\\.segment');
JUL.apply(oNS, {
	property: {a: 'A', b: 'B', c: 'C'},
	'dotted.method': function() {
		console.log('Dotted access');
	}
});
var fCall = JUL.get('NS.dotted\\.segment.dotted\\.method');
fCall();</pre><h3>Replacer-i JSON și prefixe JSON</h3><p>Unul din scopurile JUL este serializarea consistentă a obiectelor de configurare. Pentru a realiza aceasta, JUL le convertește într-un format intermediar JSON extins înainte de generarea șirului de cod JavaScript final.<br /> Locul unde se poate controla cum arată JSON-ul generat este callback-ul JUL.UI._jsonReplacer, ce joacă rolul celui de-al doilea parametru al JSON.stringify(). În interiorul acestuia, utilizatorul poate schimba ce obiecte devin șiruri de caractere și cum vor arăta ele. Implicit, în afară de tipurile standard JSON, JUL e capabil să serializeze: funcții, obiecte regex, obiecte dată. Adițional, este ușor să se obțină la ieșire rezultat pentru orice tip cunoscut de obiecte pe cază de constructor prin prefixarea apelului lor cu cuvântul cheie &#8216;new&#8217;.</p><pre class="brush:js">// un constructor ce stochează o copie a unui obiect
var Store = function(oConfig) {
	this._config = JUL.aply({}, oConfig);
};
Store.prototype.serialize = function() {
	return JUL.UI.obj2str(this._config);
};
// un parser personalizat ce poate serializa obiecte Store
var oParser = new JUL.UI.Parser({
	_jsonReplacer: function(sKey, oValue) {
		if (oValue instanceof Store) {
			return 'new Store(' + oValue.serialize() + ')';
		}
		else {
			return JUL.UI._jsonReplacer(sKey, oValue);
		}
	}
});
// producerea formei JSON pentru un obiect de configurare mixt
var oConfig = {
	dates: [new Date(), new Date() + 144000e3, new Date() + 288000e3],
	regexs: {begin: /^\s+/, end: /\s+$/},
	'a-method': function() {
		console.log('A method');
	},
	'a-store': new Store({
		item1: 'An item',
		item2: [0, 2, 4],
		item3: /(red|green|blue)/
	})
};
console.log(oParser.obj2str(oConfig, true));</pre><p>Deși șirurile generate au un format corelat cu tipurile lor, nu se poate deduce ne-echivoc aceea că un șir cu același format este obținut dintr-un obiect serializat. Pentru cazuri mai avansate, când controlul asupra codului generat este mai strict, JUL oferă conceptul prefixelor JSON.<br /> Un prefix JSON este un șir unic ce precedă șirul serializat al unui anume tip de obiect.<br /> Prefixele JSON sunt activate de către proprietatea JUL.UI._usePrefuxes și sunt stocate în hash-ul (obiectul) JUL.UI._jsonPrefixes. Predefinit, acestea sunt: prefixul pentru funcții, prefixul pentru sintaxa regex, prefixul pentru construcția &#8216;new&#8217;, dar ele pot fi adăugate sau modificate după necesități. Prefixele apar doar la forma serializată JSON a arborelui de configurare, dar nu și în forma serializată JavaScript, la care codul este direct rulabil.</p><pre class="brush:js">var oConfig = {
	xclass: 'FWK.Dialog',
	autoCenter: true,
	avatar: /(hat|suit|shirt)/i,
	validity: [new Date(Date.UTC(2017, 10, 3)), new Date(Date.UTC(2018, 10, 3))],
	listeners: {
		done: function(bQuit) {
			if (bQuit) {
				this.close();
			}
		},
		show: function(nLeft, nTop) {
			this.drawAt(nLeft, nTop);
		}
	}
};
var oParser = new JUL.UI.Parser({
	_usePrefixes: true,
	_tabString: '    '
});
console.log(oParser.obj2str(oConfig, true));</pre><h3>Referințe de cod și decoratori</h3><p>Există cazuri în care este necesar să generăm o secțiune specifică de cod ce nu poate fi stocată ca obiect de configurare. Un exemplu recurent este generarea codului altor unelte sau biblioteci JavaScript cu spațiu de nume global care sunt încărcate înainte de încărcarea configurației.<br /> Utilitara de serializare JUL.UI.obj2str() identifică aceste șiruri de cod folosind JUL.UI.referencePrefix și le generează fără ghilimele la ieșire indiferent de replacer-ul JSON și de șirurile de prefixe JSON.</p><pre class="brush:js">var oConfig = {
	tag: 'div',
	id: 'panel-tools',
	css: 'blue-panel',
	'data-control': 'Test.UI.Panel',
	'data-options': {
		instantiator: '=ref: Test.ContainerBase',
		bounding: [0, 0, 400, 200]
	}
};
var oParser = new JUL.UI.Parser({
	defaultClass: 'html',
	customFactory: 'JUL.UI.createDom',
	topDown: true,
	useTags: true
});
console.log(oParser.obj2str(oConfig));
// JUL.UI.createDom() respectă de asemenea referințele de cod din atributele elementelor
oParser.create(oConfig, null, window.document.body);</pre><p>La o privire mai atentă asupra metodei JUL.UI.obj2str(), observăm că putem schimba codul JavaScript rezultant pe măsură ce traversăm șirul JSON. JUL folosește aceste puncte de acces pentru a insera cod personalizat înaintea cheilor obiectului serializat. Primul caz de utilizare al acestor segmente de cod, denumite decoratori de cod, este inserarea comentariilor bloc pentru documentare, cum o face de ex. JCS (JUL Comment System).</p><pre class="brush:js">var oConfig = {
	property1: 'First name',
	property2: ['a', 'b', 'c'],
	metod1: function() {
		console.log('Method 1');
	}
};
var fDecorator = function(sContent, sPath, sIndent) {
		if (!sPath) { return sContent; }
		var nParts = sPath.split('.').length;
		if (nParts &gt; 1) { return sContent; }
		var oRef = JUL.get(sPath, this);
		var sText = '/**' + '\n' + sIndent + ' * ';
		switch (typeof oRef) {
		case 'function':
			sText = sText + 'Method description';
		break;
		default:
			sText = sText + 'Property description';
		}
		sText = sText + '\n' + sIndent + ' */';
		sText = sText + '\n' + sIndent + sContent;
		return sText;
};
var oParser = new JUL.UI.Parser();
console.log(oParser.obj2str(oConfig, false, fDecorator));</pre><h3>Extensibilitatea colecțiilor membri</h3><p>Pentru a parsa un arbore de configurare, JUL trebuie să știe ce membri ai obiectului de configurare reprezintă configurații de componente copil. Acest tip de informație este dată de JUL.UI.childrenProperty și de JUL.UI.membersProperties ale parser-ului. JUL.UI.childrenProperty este proprietatea principală, în timp ce vectorul JUL.UI.membersProperties poate conține nume suplimentare ale altor membri descendenți ai obiectului, iar acești membri pot fi reduși la o formă unificată folosind JUL.UI.expand(). După expandare, singurul membru copii va fi acela cu valoarea proprietății JUL.UI.childrenProperty.<br /> Dar, există situații în care proprietățile membri / copii ale unui obiect de configurare depind de clasa componentei acelei configurații. Pentru aceste cazuri JUL oferă JUL.UI.membersMappings care asociază vectorii membri la nume de clase. Mai mult, dacă un obiect de configurarea are o proprietate specială dată de valoarea lui JUL.UI.instantiateProperty, parser-ul ține cont de această proprietate membri atunci când parsează obiectul respectiv.</p><pre class="brush:js">var oTree = {
	xclass: 'Dialog',
	title: 'Title',
	content: [
		{xclass: 'BorderLayout', top: [
			{xclass: 'BorderLayoutArea', content: [
				{xclass: 'MenuBar', items: [
					{xclass: 'MenuItem', text: 'Menu 1', submenu: [
						{xclass: 'Menu', items: [
							{xclass: 'MenuItem', text: 'Submenu 1'}
						]}
					]},
					{xclass: 'MenuItem', text: 'Menu 2', submenu: [
						{xclass: 'Menu', items: [
							{xclass: 'MenuItem', enabled: false, text: 'Submenu 2'}
						]}
					]}
				]},
				{xclass: 'Toolbar', items: [
					{xclass: 'TextField', value: 'Value'},
					{xclass: 'Button', text: 'Button'}
				]}
			]}
		],
		begin: {
			xclass: 'BorderLayoutArea', content: [
				{xclass: 'ListBox'}
			]
		},
		center: {
			xclass: 'BorderLayoutArea', content: [
				{xclass: 'HTML', content: 'Content'}
			]
		}}
	]
};
var oParser = new JUL.UI.Parser({
	childrenProperty: 'items',
	membersMappings: {
		BorderLayout: ['top', 'bottom', 'begin', 'end', 'center'],
		BorderLayoutArea: 'content',
		Dialog: ['content', 'buttons'],
		MenuItem: 'submenu'
	},
	customFactory: function(oConfig) {
		console.log('Creating ' + oConfig.xclass);
		return oConfig;
	}
});
oParser.create(oTree);</pre><p>JUL are de asemenea un mod &#8216;sparse&#8217;, în care parser-ul încearcă să traverseze orice obiect copul al configurației curente pentru a căuta configurații descendente de instanțiat. În acest mod, care este declanșat de al patrulea argument al metodei JUL.UI.create(), nu este presupusă nici o clasă implicită pentru un obiect ce nu are setată proprietate clasă. În modul sparse, orice obiecte ce nu sunt configurații de componente vor fi copiate la obiectele / instanțele de ieșire cu aceeași structură de apartenentă.</p><h3>Concluzie</h3><p>Folosind JUL puteți controla multe aspecte ale arborilor de configurare și ale instanțierii lor în componente. Aceasta se aplic sarcinilor de creare, dar nu numai acestora. De fapt, JUL urmărește să fie o bază pentru dezvoltarea rapidă a unei aplicații web.<br /> Filozofia care stă în spatele JUL și a setului său de unelte este aceea că <em> o persoană nu trebuie să plătească pentru a-și putea exprima creativitatea sa pozitivă</em>.<br /> Platforma ce oferă acces gratuit și public la o astfel de dezvoltare este limbajul JavaScript. Acesta, împreună cu utilitarele sale client și server, este cu adevărat un limbaj de programare universal, depășind obstacolele întâmpinate de alte limbaje gratuite când au construit pe baza unui cod proprietar.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/concepte-avansate-jul-partea-a-2-a/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Concepte avansate JUL &#8211; partea 1</title><link>http://constructorul-zonal.xhost.ro/concepte-avansate-jul-partea-1/</link> <comments>http://constructorul-zonal.xhost.ro/concepte-avansate-jul-partea-1/#comments</comments> <pubDate>Wed, 31 May 2017 18:47:31 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JUL]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=44</guid> <description><![CDATA[Definirea unui arbore de configurare pentru construcția interfeței utilizator este una din metodele cele mai simple și directe pentru dezvoltarea rapidă a unei aplicații moderne web. JUL folosește acest arbore de configurare pentru a crea instanțele componentelor și pentru a atribui relații de apartenență părinte-copil într-o secvențialitate controlată și automată. Recapitulare a separării structurii de [&#8230;]]]></description> <content:encoded><![CDATA[<p>Definirea unui arbore de configurare pentru construcția interfeței utilizator este una din metodele cele mai simple și directe pentru dezvoltarea rapidă a unei aplicații moderne web.<br /> JUL folosește acest arbore de configurare pentru a crea instanțele componentelor și pentru a atribui relații de apartenență părinte-copil într-o secvențialitate controlată și automată.</p><h3>Recapitulare a separării structurii de logică</h3><p>Există două proprietăți ale unui obiect de configurare ce permit separarea structurii și a logicii asociate acelei configurații:</p><ol><li>Proprietatea id &#8211; identifică unic o componentă. Folosind această proprietate, putem simplifica un arbore de configurare în configurare a structurii în format arborescent și u mapare cheie-valoare cu configurare suplimentară pentru nodurile arborelui. Cheile din această a doua parte (logica de configurare) sunt valorile id. Deoarece partea de logică este un obiect de mapare cu chei, toate cheile (adică id-urile componentelor) trebuie să fie unice în aceasta. Trebuie adăugat că proprietatea id va fi pasată obiectului rezultant de configurare la instanțierea componentei.<pre class="brush:js">var oConfig = {
	xclass: 'MyApp.widgets.Avatar',
	id: 'avatar-one',
	children: [
		{xclass: 'MyApp.widgets.Hat', id: 'hat-two'},
		{xclass: 'MyApp.widgets.Suit', id: 'suit-three'}
	]
};
var oLogic = {
	'avatar-one': {
		userId: 121,
		thumbnail: 'face1.png',
		onHover: function() {
			console.log('Avatar hint');
		}
	},
	'hat-two': {
		color: 'blue',
		size: 4
	},
	'suit-three': {
		color: 'green',
		match: /(office|meeting|trip)/
	}
};
var oParser = new JUL.UI.Parser();
var oAvatar = oParser.create(oConfig, oLogic);
// apelurile runtime rezultante sunt echivalentul a:
var oHat = new MyApp.widgets.Hat({
	id: 'hat-two',
	color: 'blue',
	size: 4
});
var oSuit = new MyApp.widgets.Suit({
	id: 'suit-three',
	color: 'green',
	match: /(office|meeting|trip)/
});
oAvatar = new MyApp.widgets.Avatar({
	id: 'avatar-one',
	children: [oHat, oSuit],
	userId: 121,
	thumbnail: 'face1.png',
	onHover: function() {
		console.log('Avatar hint');
	}
});</pre></li><li>Proprietatea id de legătură &#8211; servește aceluiași scop ca și proprietatea id dar cu câteva diferențe. Proprietatea de legătură este ștearsă după agregarea porților de structură și de logică. Această proprietate poate fi de asemenea un vector, caz în care configurările adiționale referite de elementele sale sunt aplicate secvențial configurația finală. Astfel de vector este construita automat la utilizarea metodei JUL.UI.include() (a se vedea <a title="API reference" href="https://zonebuilder.github.io/jul/docs/index.html" target="_blank">referința API</a>).<pre class="brush:js">var oConfig = {
	xclass: 'MyApp.widgets.Avatar',
	id: 'the-avatar',
	cid: 'c-avatar',
	children: [
		{xclass: 'MyApp.widgets.Hat', cid: 'c-hat'},
		{xclass: 'MyApp.widgets.Suit', cid: 'c-suit'}
	]
};
var oLogic = {
	'c-avatar': {
		userId: 121,
		thumbnail: 'face1.png',
		onHover: function() {
			console.log('Avatar hint');
		}
	},
	'c-hat': {
		color: 'blue',
		size: 4
	},
	'c-suit': {
			color: 'green',
		match: /(office|meeting|trip)/
}
};
var oParser = new JUL.UI.Parser();
var oAvatar = oParser.create(oConfig, oLogic);
// apelurile runtime rezultante sunt echivalentul a:
var oHat = new MyApp.widgets.Hat({
	color: 'blue',
	size: 4
});
var oSuit = new MyApp.widgets.Suit({
	color: 'green',
	match: /(office|meeting|trip)/
});
oAvatar = new MyApp.widgets.Avatar({
	id: 'the-avata',
	children: [oHat, oSuit],
	userId: 121,
	thumbnail: 'face1.png',
	onHover: function() {
		console.log('Avatar hint');
	}
});</pre></li></ol><h3>Compunere și moștenire avansate</h3><p>A pune obiecte de configurare în arbore este forma cea mai simplă de a construi structura UI. Dar, cu ajutorul id-ului de legătură șo a metodei JUL.UI.include(), parser-ul poate combina în moduri avabsate configurațiile componentelor.</p><ol><li>Prima metodă este includerea unui obiect de configurare mai simplu într-unul mai complex. Acest proces este împărțit în două: includerea configurației de bază în structura de destinație și părții de logică a configurației de bază în logica de configurare a configurației curente. Apoi, putem repeta acest proces de mărite (extindere) a unui obiect de configurare de câte ori avem nevoie. Un exemplu al acestei metode este dat mai jos.<pre class="brush:js">var MyApp = {
	config: {},
	objects: {},
	version: '1.0'
};
MyApp.config.shapeUi = {
	xclass: 'MyLib.Shape',
	cid: 'mylib.shape',
	origin: {x: 0, y: 0}
};
MyApp.config.shapeLogic = {
	'mylib.shape': {
		color: 'grey',
		bgColor: 'white',
		getOrigin: function() {
			console.log('Shape origin');
		}
	}
};
MyApp.config.polygonUi = {
	include: MyApp.config.shapeUi,
	xclass: 'MyLib.Polygon',
	cid: 'mylib.polygon',
	corners: 0,
	sizes: []
};
MyApp.config.polygonLogic = {
	include: MyApp.config.shapeLogic,
	'mylib.polygon': {
		getArea: function() {
			console.log('Polygon area');
		}
	}
};
MyApp.config.triangleUi = {
	include: MyApp.config.polygonUi,
	xclass: 'MyLib.Triangle',
	cid: 'mylib.triangle',
	corners: 3,
	sizes: [3, 4, 5]
};
MyApp.config.triangleLogic = {
	include: MyApp.config.polygonLogic,
	'mylib.triangle': {
		draw: function() {
			console.log('Triangle draw');
		},
		getArea: function() {
			console.log('Triangle area');
		}
	}
};
var oParser = new JUL.UI.Parser();
MyApp.objects.triangle = oParser.create(MyApp.config.triangleUi, MyApp.config.triangleLogic);
// apelurile runtime rezultante sunt echivalentul a:
MyApp.objects.triangle = new MyLib.Triangle({
	origin: {x: 0, y: 0},
	corners: 3,
	sizes: [3, 4, 5],
	color: 'grey',
	bgColor: 'white',
	getOrigin: function() {
		console.log('Shape origin');
	},
	getArea: function() {
		console.log('Triangle area');
	},
	draw: function() {
		console.log('Triangle draw');
	}
});</pre><p>Acest tip de extindere se numește moștenire explicită spre deosebire de moștenirea bazată pe prototipuri sau pe clase pe care o numim moștenire implicită.  Deși am putea folosi moștenirea implicită pentru extinderea unei configurații de componentă,  JUL folosește moștenirea explicită pentru a asigura o serializare consistentă a obiectelor de configurare. Deoarece JUL.UI.obj2str() folosește intern JSON pentru a serializa obiectele, o moștenire bazată pe prototipuri ar complica procesul de serializare, date fiind diferențele prototipurilor obiectelor de-a lungul diverselor medii runtime.</li><li>A doua metodă este în introducerea de configurații de bază în diverse puncte în arborele de configurare, numită compunerea componentelor. Procesul constă în referirea către configurațiile de bază cu proprietatea include a nodului respectiv și adăugarea logicii configurației de bază la vectorul include a mapării logicii de destinație. Un exemplu de astfel de proces este dat nai jos.<pre class="brush:js">var MyApp = {
	config: {},
	objects: {},
	version: '1.0'
};
MyApp.config.circleUi = {
	xclass: 'MyLib.Circle',
	cid: 'mylib.circle',
	origin: {x: 0, y: 0},
	diameter: 1
};
MyApp.config.circleLogic = {
	'mylib.circle': {
		fillColor: 'white',
		draw: function() {
			console.log('Draw circle');
		}
	}
};
MyApp.config.rectangleUi = {
	xclass: 'MyLib.Rectangle',
	cid: 'mylib.rectangle',
	origin: {x: 0, y: 0},
	dimensions: {w: 0, h: 0},
};
MyApp.config.rectangleLogic = {
	'mylib.rectangle': {
		fillColor: 'blue',
		draw: function() {
			console.log('Draw rectangle');
		}
	}
};
MyApp.config.logoUi = {
	include: MyApp.config.rectangleUi,
	id: 'the-logo',
	dimensions: {w: 10, h: 7},
	children: [
		{include: MyApp.config.rectangleUi, id: 'inner-area', origin: {x: 1, y: 1},
		 dimensions: {w: 8, h: 5}, children: [
			{include: MyApp.config.circleUi, id: 'left-disc', origin: {x: 2, y: 2}, diameter: 3},
			{include: MyApp.config.circleUi, id: 'right-disc', origin: {x: 2, y: 5}, diameter: 3}
		]}
	]
};
MyApp.config.logoLogic = {
	include: [MyApp.config.circleLogic, MyApp.config.rectangleLogic],
	'the-logo': {
		draw: function() {
			console.log('Draw logo');
		}
	},
	'inner-area': {
		fillColor: 'yellow'
	},
	'left-disc': {
		fillColor: 'red'
	},
	'right-disc': {
		fillColor: 'green'
	}
};
var oParser = new JUL.UI.Parser();
MyApp.objects.logo = oParser.create(MyApp.config.logoUi, MyApp.config.logoLogic);
// apelurile runtime rezultante sunt echivalentul a:

var oLeft = new MyLib.Circle({
	id: 'left-disc',
	origin: {x: 2, y: 2},
	diameter: 3,
	fillColor: 'red',
	draw: function() {
		console.log('Draw circle');
	}
});
var oRight = new MyLib.Circle({
	id: 'right-disc',
	origin: {x: 2, y: 5},
	diameter: 3,
	fillColor: 'green',
	draw: function() {
		console.log('Draw circle');
	}
});
var oInner = new MyLib.Rectangle({
	id: 'inner-area',
	origin: {x: 1, y: 1},
	dimensions: {w: 8, h: 5},
	children: [oLeft, oRight],
	fillColor: 'yellow',
	draw: function() {
		console.log('Draw rectangle');
	}
});
MyApp.objects.logo = new MyLib.Rectangle({
	id: 'the-logo',
	origin: {x: 0, y: 0},
	dimensions: {w: 10, h: 7},
	children: [oInner],
	fillColor: 'blue',
	draw: function() {
		console.log('Draw logo');
	}
});</pre><p>Compunerea componentelor poate fi combinată cu moștenirea explicită pentru a obține includeri complexe ale arborilor de configurare.</li><li>A treia metodă este construirea unei noi componente folosind o funcție constructor pentru a agrega configurarea componentei într-o instanță de componentă. Această metodă poate folosi cele două metode anterioare pentru a construi configurația componentei și apoi apelează parser-ul JUL pentru a crea instanța componentei în cadrul funcției constructor. Un exemplu este dat în continuare.<pre class="brush:js">var MyApp = {
	config: {},
	objects: {},
	widgets: {},
	vesrsion: '1.0'
};
MyApp.config.logoUi = {
	xclass: 'MyLib.Ellipse',
	cid: 'c-logo',
	dimensions: {dx: 18, dy: 12},
	children: [
		{xclass: 'MyLib.Triangle', cid: 'c-inner', origin: {x: 8, y: 1},
		 sizes: [7, 7, 7], children: [
			{xclass: 'MyLib.Circle', cid: 'c-center', origin: {x: 4, y: 2}, diamerer: 4}
		]}
	]
};
MyApp.config.logoLogic = {
	'c-logo': {
		fillColor: 'green',
		Draw: function() {
			console.log('Draw logo');
		}
	},
	'c-inner': {
		fillColor: 'red',
		draw: function() {
			console.log('draw inner');
		}
	},
	'c-center': {
		fillColor: 'blue',
		draw: function() {
			console.log('Draw center');
		}
	}
};
MyApp.parser = new JUL.UI.Parser();
MyApp.widgets.Logo = function(oConfig) {
	var oApplied = {include: MyApp.config.logoUi};
	JUL.apply(oApplied, oConfig || {});
	var oAppliedLogic = {include: MyApp.config.logoLogic};
	var sId = oApplied.id || oApplied.cid;
	if (!sId) {
		sId = 'a-random-id';
		oApplied.cid = sId;
	}
	oAppliedLogic[sId] = {};
	JUL.apply(oAppliedLogic[sId], oConfig || {});
	delete oAppliedLogic[sId].xclass;
	delete oAppliedLogic[sId].id;
	delete oAppliedLogic[sId].cid;
	oApplied.xclass = MyApp.config.logoUi.xclass || MyApp.parser.defaultClass;
	return MyApp.parser.create(oApplied, oAppliedLogic);
};
MyApp.config.ui = {
	xclass: 'MyLib.Rectangle',
	id: 'the-ui',
	dimensions: {w: 22, h: 16},
	children: [
		{xclass: 'MyApp.widgets.Logo', id: 'the-logo', origin: {x: 2, y: 2}}
	]
};
MyApp.config.logic = {
	'the-ui': {
		fillColor: 'green',
		show: function() {
			console.log('Show UI');
		}
	},
	'the-logo': {
		fillColor: 'yellow'
	}
};
MyApp.objects.ui = MyApp.parser.create(MyApp.config.ui, MyApp.config.logic);
// apelurile runtime rezultante sunt echivalentul a:
var oCenter = new MyLib.Circle({
	origin: {x: 4, y: 2},
	diamerer: 4,
	fillColor: 'blue',
	draw: function() {
		console.log('Draw center');
	}
});
var oInner = new MyLib.Triangle({
	origin: {x: 8, y: 1},
	sizes: [7, 7, 7],
	children: [oCenter],
	fillColor: 'red',
	draw: function() {
		console.log('draw inner');
	}
});
var oLogo = new MyLib.Ellipse({
	id: 'the-logo',
	origin: {x: 2, y: 2},
	dimensions: {dx: 18, dy: 12},
	children: [oInner],
	fillColor: 'yellow',
	Draw: function() {
		console.log('Draw logo');
	}
});
// următorul apel va returna obiectul anterior oLogo
new MyApp.widgets.Logo({
	id: 'the-logo',
	origin: {x: 2, y: 2},
	fillColor: 'yellow'
});
MyApp.objects.ui = new MyLib.Rectangle({
	id: 'the-ui',
	dimensions: {w: 22, h: 16},
	children: [oLogo],
	fillColor: 'green',
	show: function() {
		console.log('Show UI');
	}
});</pre><p>Pentru o modalitate standard de a încapsula elemente complexe într-o componentă, consultați vă rog pagina de proiect a <a title="JWL Library" href="https://sourceforge.net/projects/jwl-library/" target="_blank">JWL Library</a>.</li></ol><h3>Moștenire circulară și meta-inițializare a parser-ului</h3><p>Un parser JUL este o instanță a JUL.UI.Parser() și moștenește automat toți membrii JUL.UI. Dar parser-ul însușii are o metodă numită Parser() care poate fi folosită pentru a construi un parser nou derivat din cel curent. Metoda Parser() acceptă ca parametru un obiect de configurare ai cărui membri pot suprascrie membrii moșteniți ai parser-ului. Mai mult, modificarea unui membru moștenit din unul din părinții ascendenți (ex. obiectul JUL.UI) se va reflecta în toți parser-ii descendenți în care acel membru nu este suprascris. Numim aceasta moștenire circulară.<br /> Parser-ul JUL se pune în acțiune atunci când este apelată metoda sa create(), care la rândul său utilizează obiectele de configurare a structurii li a logicii pentru a construi un arbore de componente. De obicei, pentru fiecare nod în structura de configurare, parser-ul creează o componentă folosind membri ai parser-ului precum proprietatea clasă, proprietatea copii, proprietatea id și așa mai departe, ca meta-informație. Dar dacă nodul procesat curent are o proprietate specială &#8211; numită implicit parserConfig, parser-ul pornește un nou parser derivat bazat pe acea proprietate pentru a construi acea ramură a arborelui de configurare. Numim aceasta meta-inițializare a parser-ului.</p><pre class="brush:js">// derivarea unui parser dintr-o clasă de bază
var oXmlParser = new JUL.UI.Parser({
	defaultClass: 'xml',
	useTags: true,
	topDown: true
});
// derivarea unui parser din cel anterior
var oHtmlParser = new oXmlParser.Parser({
	defaultClass: 'html',
	customFactory: 'JUL.UI.createDom'
});
// setarea unei proprietăți pentru o clasă de bază și pentru toți parser-ii în care proprietatea nu e suprascrisă
JUL.UI.childrenProperty = 'childNodes';
// crearea unei configurații pentru arbore DOM mixt
var oConfig = {
	tag: 'div',
	css: 'svg-wrap',
	childNodes: [
		{tag: 'h3', html: 'A SVG image'},
		{tag: 'div', css: 'svg-img', childNodes: [
			{
				// următoarea proprietate meta-informație va auto-deriva un parser nou pentru această ramură de configurație 
				parserConfig: {defaultClass: 'svg', childrenProperty: 'nodes'},
				tag: 'svg',
				width: 100,
				height: 100,
				viewBox: '0 0 100 100',
				nodes: [
					{tag: 'circle', cx: 50, cy: 50, r: 48, fill: 'none', stroke: '#000'},
		  			{tag: 'path', d: 'M50,2a48,48 0 1 1 0,96a24 24 0 1 1 0-48a24 24 0 1 0 0-48'},
		  			{tag: 'circle', cx: 50, cy: 26, r: 6},
		  			{tag: 'circle', cx: 50, cy: 74, r: 6, fill: '#FFF'}
		  		]
			}
		]}
	]
};
// crearea unui arbore DOM și atașarea lui la elementul body
oHtmlParser.create(oConfig, null, document.body);</pre><pre class="brush:html">&lt;!-- generated DOM --&gt;
&lt;div class="svg-wrap"&gt;
	&lt;h3&gt;A SVG image&lt;/h3&gt;
	&lt;div class="svg-img"&gt;
		&lt;svg:svg width="100" height="100" viewBox="0 0 100 100"&gt;
			&lt;svg:circle cx="50" cy="50" r="48" fill="none" stroke="#000"/&gt;
			&lt;svg:path d="M50,2a48,48 0 1 1 0,96a24 24 0 1 1 0-48a24 24 0 1 0 0-48"/&gt;
			&lt;svg:circle cx="50" cy="26" r="6"/&gt;
			&lt;svg:circle cx="50" cy="74" r="6" fill="#FFF"/&gt;
		&lt;/svg:svg&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre><h3>Serializare consistentă și conversie XML la JUL</h3><p>În afară de construirea componentelor dintr-un arbore de configurare, JUL urmărește să stocheze persistent și să recupereze obiectele de configurare (adică serializare). Cel nai sigur mod de a face aceasta este de a produce codul JavaScript ce va construi la rulare obiectul de configurare dorit. Pentru a îndeplini acest obiectiv, JUL folosește o serializare extinsă bazată pe standardul JSON. În plus față de regulile JSON, JUL e capabil să serializeze o serie de tipuri native de date JavaScript precum Function, RegEx, Date sau tipuri particulare de date cu ajutorul utilitarei JUL.UI._jsonReplacer(). Ținta acestei serializări poate fi fie cod JavaScript fie JSON, dar scopul este cod JavaScript echivalent indiferent unde este rulată serializarea. Numim aceasta serializare consistentă, adică procesul în care conversia obiectului de configurare produce același obiect runtime (cod JavaScript) când este executat codul rezultant. Codul propriu-zis poate diferi prin salturi de linie, spații libere, formatarea tipurilor numerice sau de tip data, dar va produce întotdeauna aceleași efecte runtime. Ca simplă observație, serializarea nu implică faptul că forma serializată trebuie să fie aceeași cu obiectul ce se serializează, deși acesta este scopul în cazul obiectelor de configurare. De reținut că obiectul runtime poate avea diverși membri prototipali sau funcționalitate extinsă depinzând de mediul unde este rulat codul. Dar obiectele de configurare JUL nu depind de prototipuri și sunt folosite doar pentru a citi configurația stocată în membrii lor. Mai multe detalii despre serializare pot fi găsite în referința metodei JUL.UI.obj2str().</p><pre class="brush:js">var oConfig = {
	firstString: 'First\t\x22string\x22\t',
	secondString: "Second 'string'\n",
	firstNumber: parseFloat(Math.PI.toFixed(4)),
	secondNumber: 1.2e4,
	dates: {
		first: new Date(Date.UTC(2020, 5, 1)),
		second: '2030-02-10T15:00:30Z'
	},
	matches: [
		/(one|two|three)\s+times/i,
		new RegExp('&lt;h1[\\s\\S]+?\/h1&gt;', 'g')
	],
	events: [
		{name: 'click', handler: "function(oEvent) {\n\tconsole.log(oEvent.type + ' triggered');\n}"},
		{name: 'change', handler: [
			function(oEvent) {
				console.log('Before ' + oEvent.type + ' triggered');
			},
			function(oEvent) {
				console.log('After ' + oEvent.type + ' triggered');
			}
		]}
	]
};
var oParser = new JUL.UI.Parser();
console.log(oParser.obj2str(oConfig));
// linia anterioară produce următorul cod JavaScript în toate mediile majore:
oConfig = {
	firstString: 'First\t"string"\t',
	secondString: 'Second \'string\'\n',
	firstNumber: 3.1416,
	secondNumber: 12000,
	dates: {
		first: new Date(/*Mon, 01 Jun 2020 00:00:00 GMT*/1590969600000),
		second: new Date(/*Sun, 10 Feb 2030 15:00:30 GMT*/1896966030000)
	},
	matches: [/(one|two|three)\s+times/i, /&lt;h1[\s\S]+?\/h1&gt;/g],
	events: [
		{name: 'click', handler: function(oEvent) {
			console.log(oEvent.type + ' triggered');
		}},
		{name: 'change', handler: [function(oEvent) {
			console.log('Before ' + oEvent.type + ' triggered');
		},
		function(oEvent) {
			console.log('After ' + oEvent.type + ' triggered');
		}]}
	]
};</pre><p>O altă facilitate a JUL este conversia de la limbajele bazate pe XML la obiectele de configurare JUL. Aceasta este realizată  de metoda JUL.UI.xml2jul() care transformă un arbore XML (sau un cod sursă) într-un arbore de configurare JUL (sau într-un cod sursă echivalent). Conversia ține cont de meta-informația parser-ului curent. Pentru a o vedea în acțiune, vizitați vă rog exemplul online <a title="XML2JUL" href="https://zonebuilder.github.io/jul/examples/xml2jul.html" target="_blank">XML2JUL</a>.</p><h3>Fabricantul personalizat</h3><p>Când construim componente din obiectul de configurare, JUL combină configurațiile de structură și de logică într-un obiect de configurare runtime pentru fiecare componentă de construit. În mod predefinit, configurația runtime este pasată unei funcții constructor localizată de calea punctată stocată în proprietatea clasă pentru această configurație. Există de asemenea și o proprietate clasă implicită care se aplică tuturor nodurilor în care proprietatea clasă nu este specificată.<br /> Utilizatorul poate schimba acest comportament prin setarea proprietății JUL.UI.customFactory la un callback de fabricare personalizat care va primit configurația calculată runtime. Un exemplu tipic de astfel de callback este metoda JUL.UI.createDom() ce pateu construi mai multe tipuri de elemente DOM (HTML, SVG, XUL etc.) în funcție de facilitățile browser-ului.</p><pre class="brush:js">// utilizarea unui fabricant JUL personalizat pentru a construi o fereastră XUL
var oConfig = {
	tag: 'window',
	id: 'window-main',
	height: 450,
	hidden: true,
	title: 'JUL News Reader',
	width: 720,
	children: [
		{tag: 'toolbox', children: [
			{tag: 'menubar', children: [
				{tag: 'toolbargrippy'},
				{tag: 'menu', label: 'File', children: [
					{tag: 'menupopup', children: [
						{tag: 'menuitem', id: 'menuitem-exit', label: 'Exit'}
					]}
				]},
				{tag: 'menu', label: 'View', children: [
					{tag: 'menupopup', children: [
						{tag: 'menuitem', id: 'menuitem-show-articles', checked: true, label: 'Show articles', type: 'checkbox'}
					]}
				]},
				{tag: 'menu', label: 'Options', children: [
					{tag: 'menupopup', children: [
						{tag: 'menuitem', id: 'menuitem-autorefresh', label: 'Autorefresh every minute', type: 'checkbox'}
					]}
				]}
			]}
		]},
		{tag: 'hbox', children: [
			{tag: 'spacer', width: 7},
			{tag: 'label', control: 'textbox-url', value: 'Address'},
			{tag: 'spacer', width: 7},
			{tag: 'textbox', id: 'textbox-url', flex: 1, value: 'http://feeds.skynews.com/feeds/rss/technology.xml'},
			{tag: 'spacer', width: 5},
			{tag: 'button', id: 'button-go', label: 'Go', tooltiptext: 'Get the news', width: 50}
		]},
		{tag: 'hbox', flex: 1, children: [
			{tag: 'vbox', id: 'vbox-articles', width: 260, children: [
				{tag: 'listbox', id: 'listbox-articles', flex: 1, children: [
					{tag: 'listhead', children: [
						{tag: 'listheader', label: 'Article', width: 500}
					]},
					{tag: 'listbody'}
				]}
			]},
			{tag: 'splitter'},
			{tag: 'vbox', width: '100%', children: [
				{tag: 'description', id: 'description-title'},
				{tag: 'description', id: 'description-date'},
				{tag: 'hbox', id: 'hbox-image', hidden: true, pack: 'center', children: [
					{tag: 'image', id: 'image-article', width: 200}
				]},
				{tag: 'description', id: 'description-content'}
			]}
		]}
	]
};
var oParser = new JUL.UI.Parser({
	customFactory: 'JUL.UI.createDom',
	defaultClass: 'xul',
	topDown: true,
	useTags: true
});
var oWindow = oParser.create(oConfig);
oWindow.show();</pre><h3>Va urma</h3><p>Acestea au fost câteva concepte avansate despre utilizarea JUL &#8212; limbajul UI JavaScript. Alte concepte precum replacer-i JSON particularizați, prefixe pentru serializare, decoratori ai codului, accesarea și setarea scopului callback-urilor, escaping al caii punctate și ala mai departe, vor fi discutate într-un articol viitor.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/concepte-avansate-jul-partea-1/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Referințe în JavaScript</title><link>http://constructorul-zonal.xhost.ro/referinte-in-javascript/</link> <comments>http://constructorul-zonal.xhost.ro/referinte-in-javascript/#comments</comments> <pubDate>Wed, 12 Oct 2016 17:28:51 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[JavaScript]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=42</guid> <description><![CDATA[Există o serie de mituri despre limitele JavaScript în ce privește trăsăturile moderne ale unui limbaj de programare. Unul dintre acestea este afirmația că ar trebui să declarați variabilele locale la începutul unei funcții deoarece ele există de-a lungul scopului local al acelei funcții. Deși variabilele locale nu sunt restricționate la nivel de scop al [&#8230;]]]></description> <content:encoded><![CDATA[<p>Există o serie de mituri despre limitele JavaScript în ce privește trăsăturile moderne ale unui limbaj de programare. Unul dintre acestea este afirmația că ar trebui să declarați variabilele locale la începutul unei funcții deoarece ele există de-a lungul scopului local al acelei funcții. Deși variabilele locale nu sunt restricționate la nivel de scop al unui bloc precum în alte limbaje OOP, ele există totuși doar după locul unde au fost declarate. Astfel, codul în care acestea apar la început și codul în care acestea apar prima dată acolo unde sunt declarate, deși ambele valide, nu sunt echivalente (scopul de acces nu e același u scopul de existență). De fapt, este mai lizibil să declari un contor care nu e folosit decât după 20 de linii de cod, în cel loc, decât să aglomerezi începutul funcției cu variabile auxiliare. Chiar dacă declarați de două ori un contor local, browser-ele moderne nu se vor bloca acolo și puteți curăța codul final cu <a href="http://www.sitepoint.com/comparison-javascript-linting-tools/" target="_blank">JSLint/JSHint/ESLint</a> pentru a evita duplicatele.<br /> Ali mit mai important este acela că deoarece sunt mereu <a href="http://snook.ca/archives/javascript/javascript_pass" target="_blank">transmise prin valoare </a>, în JavaScript nu se poate programa cu pointer-i sau referințe. Deși sintaxa limbajului folosește caracterul punct pentru a se referi la membrii unui obiect, nu există nici un mecanism pentru a le accesa adresele (adică pointer-i). Dar, când obiectul este pasat unei funcții, motorul limbajului face o copie a obiectului, dar nu face și copii ale membrilor săi. Specificația precizează că membrii copiei sunt membrii inițiali ai obiectului original. Deci, ce este copiat în acest caz?<br /> Membrii unui obiect ar trebui priviți ca fiind legați la obiectul lor părinte, în loc să fie incluși în interior. Când obiectul este copiat, legăturile la membrii săi sunt cele care devin copiate, și nu membrii. O întrebare ar putea apărea: ce sunt aceste legături? Răspunsul este legat de o altă facilitate a JavaScript: colectarea memoriei alocate. Este specificat că atunci când o variabilă nu mai este folosită, memoria alocată pentru acea variabilă este eliberată de motorul de colectare. Mai mult, anumite implementări <a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management" target="_blank">precizează</a> că atunci când numărul de referințe către un obiect ajunge la zero, acel obiect candidează la colectarea memoriei alocate. Aceasta este o dezvăluire despre faptul că acele legături la membrii obiectului nu sunt simple legături, ele sunt mai degrabă referințele sau pointer-ii întâlnite în celelalte limbaje OOP.<br /> Pentru a exemplifica limitarea percepută la manevrarea membrilor obiectului în JavaScript, în cele ce urmează, vor fi propuse două situații.</p><h3>Problema</h3><p>1. Să presupunem că dorim să schimbăm între ele două obiecte în funcție de una din proprietățile lor. Codul de mai jos ilustrează soluția clasică.</p><pre class="brush:js">var data = {
	version: '0.01',
	isTest: true,
	first: {
		id: 'a11',
		weight: 1.1,
		size: 2.0
	},
	second: {
		id: 'b10',
		weight: 0.5,
		size: 1.4
	}
};
// încercăm o interschimbare generică, nu va funcționa
function swap1(o1, o2, sortBy) {
	var o = null;
	if (o2[sortBy] &lt; o1[sortBy]) {
		o = o1;
		o1 = o2;
		o2 = o;
	}
}
swap1(data.first, data.second, 'weight');
alert('first: ' + data.first.id + ', second: ' + data.second.id);

// aceasta va funcționa, dare dependentă de structura datelor
function swap2(parent, sortBy) {
	var o = null;
	if (parent.second[sortBy] &lt; parent.first[sortBy]) {
		o = parent.first;
		parent.first = parent.second;
		parent.second = o;
	}
}
swap2(data, 'weight');
alert('first: ' + data.first.id + ', second: ' + data.second.id);</pre><p>Dar putem observa că avem nevoie să modificăm declarația inițială a funcției swap(), iar codul din interiorul său este dependent de structura obiectului părinte.<br /> 2. O listă de articole este recepționată de la partea de server, trebuie să fie procesată pentru afișare în funcție de anumite câmpuri și adăugat un alt câmp calculat. Funcția qr() ce face procesarea necesită un cod ca cel de mai jos.</p><pre class="brush:js">// structura inițială
var result1 = {
	meta: {
		weightField: 'w',
		sizeField: 's',
		qrField: 'q'
	},
	items: [
		{id: 'c20', w: 2.1, s: 0.15, q: false},
		{id: 'c21', w: 1.5, s: 1.05, q: false},
		{id: 'c22', w: 1.8, s: 2.20, q: false}
	]
};
function qr1(item, weightField, sizeField, qrField) {
	if (item[sizeField] &lt; 0.5) {
		item[qrField] = 100 * item[weightField];
	}
	else {
		item[qrField] = 25 * item[sizeField] + 75 * item[weightField];
	}
	item[weightField] = 100 * item[weightField] / item[qrField];
	item[sizeField] = 100 * item[sizeField] / item[qrField];
}

// structura modificată
var result2 = {
	meta: {
		weightField: 'we',
		sizeField: 'sz',
		qrField: 'qr',
		qmField: 'qm'
	},
	items: [
		{id: 'c20', dataIn: {we: 2.1, sz: 0.15}, dataOut: {qr: false, qm: false}},
		{id: 'c21', dataIn: {we: 1.5, sz: 1.05}, dataOut: {qr: false, qm: false}},
		{id: 'c22', dataIn: {we: 1.8, sz: 2.20}, dataOut: {qr: false, qm: false}}
	]
};
function qr2(itemIn, weightField, sizeField, itemOut, qrField) {
	if (itemIn[sizeField] &lt; 0.5) {
		itemOut[qrField] = 100 * itemOut[weightField];
	}
	else {
		itemOut[qrField] = 25 * itemIn[sizeField] + 75 * itemIn[weightField];
	}
	itemIn[weightField] = 100 * itemIn[weightField] / itemOut[qrField];
	itemIn[sizeField] = 100 * itemIn[sizeField] / itemOut[qrField];
}</pre><p>Dar, dacă numele sau structura datelor de pe partea de server se schimbă, trebuie modificat codul din interiorul funcției qr() deși algoritmul de calcul nu s-a schimbat deloc.<br /> Aceste exemple arată că mare parte din codul JavaScript este dependent de structura datelor procesate și necesită mentenanță continuă la schimbarea sursei de date. Ei &hellip; dar nu pentru mult timp &hellip;</p><h3>Introducere în referințe în JavaScript</h3><p>O referință în JavaScript este o pereche formată dintr-un obiect JavaScript existent și un șir de caractere/număr ce este folosit drept cheie pentru acel obiect.<br /> Obiectul este denumit obiect proprietar/referit, iar șirul de caractere este denumit articolul/cheia referinței. Cheia poate fi absentă în obiectul referit la momentul referinței.<br /> Cea mai simplă implementare în JavaScript este un hash (obiect) cu două proprietăți ce stochează proprietarul și articolul, ca în codul următor.</p><pre class="brush:js">var data = {
	group: 'widgets',
	control: 'Panel',
	style: {
		fonts: ['Helvetica', 'Gerorgia', 'Traffic'],
		borders: {inner: '1px', outer: '2px'},
		visible: true
	}
};
// creare referințe
var p1 = {ref: data.style, key: 'visible'};
var p2 = {ref: data.style.fonts, key: 2};
var p3 = {ref: data.style.borders, key: 'inner'};
// atribuirea unei valori
p1.ref[p1.key] = false;
p2.ref[p2.key] = 'Verdana';
// aplicarea operatorului delete
delete p3.ref[p3.key];
// copierea unei referințe
var p4 = {ref: p3.ref, key: p3.key};
// schimbarea cheii
p4.key = 'shadow';
p4.ref[p4.key] = '4px';
/* the resulting object will be:
data = {
	group: 'widgets',
	control: 'Panel',
	style: {
		fonts: ['Helvetica', 'Georgia', 'Verdana'],
		borders: {outer: '2px', shadow: '4px'},
		visible: false
	}
};
------------------------------ */</pre><p>După cum se poate vedea, putem implementa toate operațiile de bază cu acest concept de referință. Dar ce avantaj ar putea fi aceasta la problema codului JavaScript dependent de date?</p><h3>Soluția &#8211; generici</h3><p>Numim generic, un fragment de cod sau un algoritm care nu se modifică atunci când datele pasate/procesate își schimbă structura (denumirea câmpurilor, apartenența câmpurilor etc.).<br /> Folosind referințe, putem construi funcții generice pentru cele două probleme exemplu menționate anterior. Dacă structura datelor se schimbă, trebuie modificat doar apelul efectiv al genericului, iar nu și codul său intrinsec.<br /> 1.</p><pre class="brush:js">function swap(p1, p2, sortBy) {
	var o = null;
	var o1 = p1.ref[p1.key];
	var o2 = p2.ref[p2.key];
	if (o2[sortBy] &lt; o1[sortBy]) {
		o = o1;
		p1.ref[p1.key] = o2;
		p2.ref[p2.key] = o;
	}
}
// apelul
swap({ref: data, key: 'first'}, {ref: data, key: 'second'}, 'weight');
alert('first: ' + data.first.id + ', second: ' + data.second.id);</pre><p>2.</p><pre class="brush:js">function qr(pWeight, pSize, pQr) {
	if (pSize.ref[pSize.key] &lt; 0.5) {
		pQr.ref[pQr.key] = 100 * pWeight.ref[pWeight.key];
	}
	else {
		pQr.ref[pQr.key] = 25 * pSize.ref[pSize.key] + 75 * pWeight.ref[pWeight.key];
	}
	pWeight.ref[pWeight.key] = 100 * pWeight.ref[pWeight.key] / pQr.ref[pQr.key];
	pSize.ref[pSize.key] = 100 * pSize.ref[pSize.key] / pQr.ref[pQr.key];
}
// fie: var item = data.items[i]; // în interiorul unei bucle
// apelul în primul caz
qr({ref: item, key: 'w'}, {ref: item, key: 's'}, {ref: item, key: 'q'});
/// apelul în cazul al doilea
qr({ref: item.dataIn, key: 'we'}, {ref: item.dataIn, key: 'sz'}, {ref: item.dataOut, key: 'qr'});</pre><h3>O clasă referință în JavaScript</h3><p>Modulul de <a title="JUL - Limbajul UI JavaScript" href="/jul-limbajul-ui-javascript/">Limbaj UI JavaScript </a> conține o implementare a unei clase pentru lucrul cu referințe. Utilizând clasa <a title="JUL API Reference" href="https://zonebuilder.github.io/jul/docs/index.html" target="_blank">JUL.Ref</a>, codul pentru operațiile de bază poate fi rescris după cum urmează.</p><pre class="brush:js">var p1 = new JUL.Ref(data.style, 'visible');
var p2 =  new JUL.Ref(data.style.fonts, 2);
var p3 =  new JUL.Ref(data.style.borders, 'inner');
// atribuirea unei valori
p1.val(false);
p2.val('Verdana');
// aplicarea operatorului delete
p3.del();
// copierea unei referințe
var p4 = new JUL.Ref(p3);
// schimbarea cheii
p4.key('shadow');
p4.val('4px');</pre><h3>Concluzie</h3><p>Conceptul de referințe în JavaScript umple golul în care pointer-i sau referințe la variabile sunt necesare în celelalte limbaje de programare. El oferă de asemenea un mod de a implementa generici în JavaScript, ceea ce conduce la posibila existență a unei biblioteci standard de algoritmi pentru JavaScript (ca STL în C++).<br /> La o examinare mai atentă, ca limbaj de programare, lui JavaScript nu îi lipsește nimic din ceea ce au celelalte limbaje moderne și este un pariu câștigător pentru platforma cloud (web, mobil, net-pc) a aplicațiilor.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/referinte-in-javascript/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>JUL Designer &#8211; o unealtă RAD pentru JavaScript</title><link>http://constructorul-zonal.xhost.ro/jul-designer-o-unealta-rad-pentru-javascript/</link> <comments>http://constructorul-zonal.xhost.ro/jul-designer-o-unealta-rad-pentru-javascript/#comments</comments> <pubDate>Mon, 01 Dec 2014 20:25:36 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[Dezvoltare web]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JUL]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=36</guid> <description><![CDATA[Construirea unei aplicații web complete necesită ceva talent și anumite unelte. În vreme ce talentul se dezvoltă pe măsura studierii li a testării, uneltele necesare par depindă mai ales de platforma de dezvoltare aleasă. Când vine vorba despre biblioteci JavaScript, mulși autori au creat uneltele potrivite framework-urilor lor și filozofiei acestora. Și, după inițierea unui [&#8230;]]]></description> <content:encoded><![CDATA[<p>Construirea unei aplicații web complete necesită ceva talent și anumite unelte. În vreme ce talentul se dezvoltă pe măsura studierii li a testării, uneltele necesare par depindă mai ales de platforma de dezvoltare aleasă. Când vine vorba despre biblioteci JavaScript, mulși autori au creat uneltele potrivite framework-urilor lor și filozofiei acestora. Și, după inițierea unui framework de larg acces ce promite libertate și productivitate utilizatorilor săi, cei mai mulți autori creează unelte proprietare pentru acesta, punând o etichetă  cu prețul pe biblioteca lor gratuită.<br /> JUL Designer oferă o modalitate puternică de a construi vizual o aplicație folosind oricare din framework-urile dvs. preferate, protejându-vă în același timp libertatea de alegere și creativitatea dvs. Filozofia sa este de a rămâne deschis și gratuit pentru orice efort creativ.<br /> Bazat pe <a title="JUL - Limbajul UI JavaScript" href=" /jul-limbajul-ui-javascript/">JUL</a>, designer-ul sporește puterea de organizare și de structurare a lui JUL la nivel de construcție vizuală, editare și testare a proiectului dvs.<br /> Arborele de configurare specific lui JUL poate fi construit acum prin editare li selectare folosind o interfață grafică, iar rezultatele sunt afișate în timp real în zona de testare. Selecția componentelor funcționează în ambele moduri de la arborele de componente al proiectului dar și di aplicația testată. În acest fel, veți ști întotdeauna unde și ce componentă să editați și cum să-i afectați membrii.<br /> Aruncați o privire pe versiunea demonstrativă de mai jos și încărcați exemplele pentru a vedea cum funcționează. Versiunea completă și gratuită poate fi descărcată din <a title="proiectul JUL Designer pe SourceForge" href="http://sourceforge.net/projects/jul-designer/" target="_blank">pagina proiectului</a>.</p><p><a title="JUL Designer" href="https://zonebuilder.github.io/designer/index.html" target="_blank"><img class="aligncenter size-full wp-image-167" alt="JUL Designer" src="/site-ro/wp-content/uploads/2014/12/designer.png" width="1366" height="768" /></a></p><p>Operațiile în designer acoperă întreaga manipulare a arborelui de componente: copiere, decupare, alipite, mutarea și eliminarea unei componente și a descendenților săi, dar și copierea, decuparea, alipirea și eliminarea mai multor membri ai unei componente. La fiecare pas din editarea proiectului, designer-ul generează dinamic codul JavaScript și reflectă schimbările în zona de testare live.<br /> Puteți folosi oricare din bibliotecile dvs. favorite de widget-uri sau framework-uri de componente cu JUL Designer prin simpla adăugare a configurațiilor de componente cu opțiunea de meniu &#8220;New framework&#8221;. Framework-ul activ curent va oferi designer-ului mijloacele pentru adăugarea și selectarea componentelor în orice proiect activ. Mai multe informații despre utilizarea designer-ului pot fi găsite la <a title="JUL Designer Help" href="https://zonebuilder.github.io/designer/docs/index.html" target="_blank">pagina de asistență a aplicației</a>.<br /> Să sperăm că această unealtă vă va îmbunătăți productivitatea și vă va oferi acces la construirea unei mari aplicații JavaScript cu generator de cod vizual gratuit.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/jul-designer-o-unealta-rad-pentru-javascript/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>De ce JavaScript?</title><link>http://constructorul-zonal.xhost.ro/de-ce-javascript/</link> <comments>http://constructorul-zonal.xhost.ro/de-ce-javascript/#comments</comments> <pubDate>Mon, 04 Aug 2014 13:32:46 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[Dezvoltare web]]></category> <category><![CDATA[JavaScript]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=30</guid> <description><![CDATA[Software-ul modern migrează masiv către platforma web. Dar, în timp ce tendința e aceeași în toată lumea, implementările variază substanțial. Pe partea de server, există cele nai diverse framework-uri și o serie de limbaje de programare precum PHP, Java, .NET. Pe partea de client, lucrurile sunt ceva mai simple, cu framework-uri ce manipulează un mediu [&#8230;]]]></description> <content:encoded><![CDATA[<p>Software-ul modern migrează masiv către platforma web. Dar, în timp ce tendința e aceeași în toată lumea, implementările variază substanțial. Pe partea de server, există cele nai diverse framework-uri și o serie de limbaje de programare precum PHP, Java, .NET. Pe partea de client, lucrurile sunt ceva mai simple, cu framework-uri ce manipulează un mediu similar DOM al browser-elor web.<br /> O aplicație web se bazează pe interfața (GUI) browser-ului și pe motorul de procesare al acestuia pentru a-și rula partea client. Aceste interacțiuni au fost standardizat ca <a href="https://en.wikipedia.org/wiki/Document_Object_Model" target="_blank">Modelul Document Obiect</a> (DOM) 2 sau 3. Pentru a implementa partea client, este necesară cunoașterea limbajului de markup HTML pentru structură, a limbajului de stiluri CSS pentru aspect și a limbajului JavaScript pentru comportament la client. Dar, în timp ce cunoașterea acestor trei domenii este obligatorie pentru asigurarea unei experiențe complete utilizator, mecanismele ce le susțin vin toate dintr-un singur model pe componente.</p><h2>JavaScript &#8211; limbajul DOM</h2><p>Dezvoltatorii de browser-e au adoptat conceptul de GUI orientat pe evenimente din munca anterioară la sistemele de operare GUI. Nu-i astfel de mirare că și implementarea dezvoltării de browser-e partajează o serie de concepte de programare cunoscute anterior precum OOP, COM, RPC, cozi de evenimente, propagarea la suprafață a evenimentelor (event bubbling) și așa mai departe. Dacă luăm de exemplu un browser generic scris în Java, motoarele de structură, stil și comportament vizează aceleași componente runtime GUI scrise în Java OOP. Aceasta înseamnă că toate aspectele unei componente pot fi controlate complet utilizând limbajul de dezvoltare (adică Java). Dar din punct de vederea al browser-ului web suntem constrânși la a utiliza limbaje standard de markup, de stil și de comportament. Analog cu cazul interfețelor <a href="https://en.wikipedia.org/wiki/Component_Object_Model" target="_blank">COM</a>, acestea sunt diverse limbaje care accesează aceleași componente runtime &#8211; GUI-ul browser-ului. Luate separat, HTML, CSS și JavaScript au un grad de acces la componenta runtime limitat și, s-ar părea că este nevoie de toate trei pentru a controla în întregime partea client a unei aplicații web. Dar asta nu e adevărat &hellip;<br /> În lumea aplicațiilor web, HTML joacă rolul unui limbaj de structurare a datelor precum XML. El descrie mai ales layout-ul componentelor aplicației și, cu grad limitat de succes, proprietățile lor runtime. În lumina modelului de dezvoltare a browser-ului prezentat anterior, acesta se manifestă ca limbajul de scripting &#8220;al omului sărac&#8221; folosit pentru a accesa motoarele de structură și de desenare ale browser-ului.<br /> CSS este un limbaj de stil global cu utilizare extinsă și în afara platformei web. În cazul browser-ului, acesta accesează motoarele de structură și de desenare cu și mai puțin control decât HTML. Dar este esențial pentru a asigura modelul de scară largă al separării preocupărilor, în care sarcinile de designer și de programator sunt clar separate.<br /> În vreme ce HTML și CSS pot fi considerate limbaje de scripting cu un anume nivel de control asupra GUI-ului browser, JavaScript este limbajul de scripting cel mai apropiat de limbajul implementării GUI și joacă un rol similar cu cel al limbajelor de scripting pentru interfețele COM. Toate trei aspectele de structură, stilizare și comportament pot fi controlate folosind JavaScript. Aceasta se întâmplă deoarece JavaScript urmărește în modul cel mai apropiat modelul bazat pe evenimente al implementării browser-ului. La o ptivire mai atentă, se poate genera o întreagă aplicație folosind javaScruot sau cu un framework de nivel ridicat precum <a href="https://en.wikipedia.org/wiki/GWT" target="_blank">GWT</a> care la rândul său generează JavaScript-ul necesar.</p><h2>JavaScript înseamnă putere în paranteze</h2><p>Limbajele moderne de programare oferă biblioteci cu grad înalt de abstractizare precum STL pentru utilizarea structurilor de date, iteratorilor, algoritmilor și așa mai departe. O sarcină uzuală este aceea de a organiza și de a accesa colecții eterogene de obiecte. Aceasta se realizează în general folosind perechi identificabile prin nume de tip cheie-valoare denumite hash-uri. Chiar și membrii clasici ai structurilor sau ai claselor pot fi priviți ca proprietăți cu nume ce indică spre anumite valori. Domeniul hash-urilor este unul din câmpurile la care JavaScript excelează. Implementarea este cât mai simplă, orice obiect putând fi considerat un hash al proprietăților sale. În JavaScript, orice obiect care nu este o variabilă locală poate fi accesat utilizând obiectul rădăcină (window) și p serie de șiruri de caractere sau de numere întregi.<br /> Exemplu:</p><pre class="brush:js">// stocarea unei configurații
window.myConfig = {
	title: 'Sample app',
	layout: {
		align: ['left', 'top'],
		coordinates: [0, 0, 500, 200],
		doubleFrame: true
	}
};
// accesarea celei de-a patra coordonate folosind doar notația paranteză
var nForth = window['myConfig']['layout']['coordinates'][3];
// această proprietate poate fi stocată în și citită dintr-un fișier text ex.
// myConfig.layout.coordinates.3 = 200</pre><p>Aceasta oferă limbajului o putere imensă pentru generarea și manevrarea secvențelor de cod plecând de la structuri de date. Pentru majoritatea cazurilor de generare de cod, cu ajutorul notației de tip paranteză dreaptă, poate fi complet evitată folosirea funcției eval().<br /> JavaScript are și construcția for .. in ce iterează peste proprietăți cu sau fără nume cum o fac și iteratorii altor limbaje. Pentru momentul la care JavaScript a fost dezvoltat. Facilitățile limbajului erau revoluționare. Pentru zilele noaste, cu puțină atenție, JavaScript poate funcționa la paritate cu limbajele moderne OOP.</p><h2>ECMA, eliberează JavaScript!</h2><p>În comparație cu limbajele moderne OOP de scripting precum Python sau PHP5, lui JavaScript îi lipsesc câteva trăsături care fac ciclul de dezvoltare pregătit pentru scară largă. Prima chestiune cunoscută este lipsa unui model de moștenire bazat pe clase, adresată de <a href="https://en.wikipedia.org/wiki/Ecma_International" target="_blank">ECMA</a> prin draft-uri ca Harmony, dar surprinzător nu încă standardizat. P altă cerință de maturitate este implementarea algoritmilor standard și a bibliotecilor de bază cum are de ex. PHP. Dar am observat în topicul anterior cum notația paranteză facilitează lucrul cu hash-uri și iterearea colecțiilor. O altă facilitate cerută  de mediile prezente este p formă compilată a limbajului independentă de arhitectură cum au Java sau .NET. Dar în toate browser-ele majore sunt implementate <a href="https://en.wikipedia.org/wiki/List_of_JavaScript_engines" target="_blank">Compilatoare JIT pentru  JavaScript</a> și e doar o problemă de coordonare politică până când echipele de dezvoltare vor propune un draft privind această facilitate. Deși din rațiuni de securitate, codul sursă JavaScript trebuie să fie disponibil pentru clienții web, o formă standard compilată va aduce JavaScript la maturitatea limbajelor preferate în business-ul software. Metodele curente de compresare sau obfuscare a codului sursă JavaScript sunt doar un mod de a pretinde această cerință necesară. O formă standard compilată adaigă un nivel superior de protecție a dreptului de autor în comparație cu simpla semnare a codului sursă original și ca fi mult mai rapid de descărcat și de executat.<br /> Acestea sunt doar câteva cerințe ce fac JavaScript să treneze față de alte platforme de dezvoltare. Dar motivul întârzierii ar trebui identificat în interesele corporatiste ale jucătorilor majori din lumea dezvoltatorilor. Doar prin vocea unită a comunității poate fi depășită opacitatea comisiei de standardizare și să se impună până la urmă aceste cerințe populare. Și, dacă ECMA nu poate rezolva problema, putem crea noi standardul concret și util în locul lor. Priviți doar la multitudinea implementărilor de <a href="http://ajaxpatterns.org/Javascript_Inheritance" target="_blank">sisteme de clase</a> pentru acest util limbaj prototipal.</p><h2>JavaScript poate servi!</h2><p>O aplicație web modernă are o parte pe server care asigură stabilitatea și securitatea procesării datelor. Cele mai folosite platforme pentru partea de server sunt PHP, Java și .NET. Toate sunt framework-uri mature cu limbaj de programare la zi și o suită puternică de biblioteci. Între acestea, PHP și-a câștigat popularitatea datorită bibliotecilor integrate de tip &#8220;bun la toate&#8221; ce par să fie rețeta de succes pentru o suită de server utilă.<br /> Până în anii recenți, JavaScript era limitat la emisfera părții client din cauza absenței unei suite de server utile. Aceasta nu mai este o problemă de la recuperarea rapidă de teren de către <a href="https://en.wikipedia.org/wiki/Node.js" target="_blank">Node.js</a> care urmărește să aducă o popularitate ca cea a PHP pentru JavaScript pe partea de server. Când acest proiect reușește, JavaScript poate fi folosit unitar atât pe partea client câr și pe cea de server.  Dezvoltatorii se pot concentra pe logica de business în locul învățării unor limbaje diferite doar pentru a putea să realizeze o aplicație.</p><h2>Concluzie</h2><p>JavaScript a fost inventat ca un limbaj web evoluționar cu colectarea memoriei alocate, manipulare de nivel înalt a șirurilor de caractere și a hash-urilor, motor de expresii refulare și o serie de trăsături utile ce nu se limitează la programarea web.<br /> Este doar contextul jucătorilor majori ce a prejudiciat drumul său ca limbaj de programare global, dar capturarea de către aceștia la platforme proprietare nu mai poate continua în epoca actuală.<br /> Folosiți JavaScript și susțineți-l ca limbaj universal de programare și lumea va adera la indeniabil!</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/de-ce-javascript/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Concepte JUL</title><link>http://constructorul-zonal.xhost.ro/concepte-jul/</link> <comments>http://constructorul-zonal.xhost.ro/concepte-jul/#comments</comments> <pubDate>Thu, 22 May 2014 14:53:25 +0000</pubDate> <dc:creator><![CDATA[ZB]]></dc:creator> <category><![CDATA[JUL]]></category><guid isPermaLink="false">http://constructorul-zonal.xhost.ro/?p=22</guid> <description><![CDATA[După cum am văaut în articolul inițial, modulul de limbaj UI JavaScript (JUL) poate fi folosit pentru a converti o sarcină substanțială de programare într-o scriere a unei configurații. Acest lucru este posibil deoarece JUL gestionează fazele de configurare și de instanțiere într-un mod standardizat pentru orice framework JavaScript bazat pe componente. Și, deoarece obiectivul [&#8230;]]]></description> <content:encoded><![CDATA[<p>După cum am văaut în <a title="JUL - Limbajul UI JavaScript" href="/jul-limbajul-ui-javascript/">articolul inițial</a>, modulul de limbaj UI JavaScript (JUL) poate fi folosit pentru a converti o sarcină substanțială de programare într-o scriere a unei configurații.<br /> Acest lucru este posibil deoarece JUL gestionează fazele de configurare și de instanțiere într-un mod standardizat pentru orice framework JavaScript bazat pe componente. Și, deoarece obiectivul majorității acestor framework-uri este o aplicație cu interfață complexă (RIA) ce rulează în browser, JUL oferă un mod unitar de a descrie structura și logica interfeței pentru aplicațiili browser bazate pe evenimente.<br /> Pentru a-i putea utiliza pe deplin capacitățile, vom vedea în cele ce urmează conceptele pe care se bazează JUL. Toată discuția se va purta în contextul programării JavaScript și DOM cât timp nu se specifică altfel.</p><h2>Obiect de configurare</h2><p>Un obiect de configurare este un obiect JavaScript care poate avea următoarele tipuri de membri:</p><ul><li>toate tipurile valide JSON: șir de caractere, număr, boolean, nul, obiect, vector</li><li>o instanță RegExp</li><li>definiția unei funcții (adică o instanță Function)</li><li>un obiect de configurare</li><li>un vector de obiecte de configurare</li></ul><p>Exemplu:</p><pre class="brush:js">APP.codeUi = {
	tag: 'dialog',
	id: 'dialog-code',
	title: 'Code',
	hidden: true,
	width: 700,
	height: 330,
	children: [
		{tag: 'textbox', id: 'textbox-code', width: '100%', multiline: true, flex: 1}
	],
	listeners: {
		dialogaccept: function() {
			APP.saveCode();
			return false;
		},
		dialogcancel: function() {
			APP.cancelCode();
			return false;
		}
	}
};</pre><h2>Arbore de configurare</h2><p>Un arbore de configurare este o ierarhie de obiecte de configurare cu obiectul rădăcină având anumiți membri (vectori de) obiecte de configurare și așa mai departe pentru descendenți.</p><h2>Spațiu-nume de configurare</h2><p>Un spațiu-nume de configurare este un obiect de configurare ai cărui membri pot fi funcții constructor.<br /> Exemplu:</p><pre class="brush:js">JUL.UI = {
lassProperty: 'xclass',
	defaultClass: 'Object',
	...
	// următoarea funcție este folosită drept constructor
	Parser: function(oConfig) { ... },
	...
};</pre><h2>Cale punctată</h2><p>O cale punctată sau o cale pe obiecte este șirul de caractere ce reprezintă variabila JavaScript necesară pentru a accesa ca membru un obiect pornind de la obiectul global JavaScript ca rădăcină (ex. window). O cale punctată folosește doar puncte pentru a-și separa segmentele (inclusiv pentru segmentele numerice).<br /> Exemplu:</p><pre class="brush:js">APP.mainWindow = {
	xclass: 'Window',
	align: 'center',
	width: 1100,
	height: 500,
	children: [
		{xclass: 'Toolbar', items: [
			{xclass: 'Button', icon: 'img/open.png', caption: 'Open'},
			{xclass: 'Button', icon: 'img/save.png', caption: 'Save'},
			{xclass: 'List', label: 'Export', options: ['pdf', 'text', 'xml']}
		]},
		...
	]
};
// obținere vector listă de opțiuni folosind o cale punctată
var aOptions = JUL.get('APP.mainWindow.children.0.items.2.options');</pre><h2>Serializare consistentă</h2><p>Serializarea consistentă este serializarea unui obiect JavaScript ce produce cod JavaScript echivalent de-a lungul diferitelor medii runtime (ex. bbrowser-e). Codul rezultat trebuie să producă un obiect având aceiași membri non-prototip pentru toate aceste medii. În JUL, serializarea consistentă trebuie să producă același obiect de configurare ca și cod JavaScript pentru toate browser-ele importante.<br /> Observație: Obiectul ce se serializează nu trebuie să nu fie neapărat identic cu obiectul produs de codul serializat JavaScript.<br /> Exemplu:</p><pre class="brush:js">var oTest = {
	name: 'type',
	maxLength: 10,
	allowedValues: /^(boolean|numeric|string)$/i,
	listeners: {
		onBlur: function() {
			if (!this.value) { return false; }
		}
	}
};
// următoarea linie produce cod JavaScript echivalent în toate browser-ele majore
var sCode = JUL.UI.obj2str(oTest);</pre><h2>Membri speciali</h2><p>Un obiect de configurare poate avea printre alții, următorii membri speciali:</p><ul><li>proprietatea clasă &#8211; un șir de caractere ce reprezintă numele clasei componentei create de obiectul de configurare.</li><li>proprietatea copii &#8211; un vector de obiecte de configurare pentru care JUL va crea componente copil.</li><li>proprietatea alți membri &#8211; servește aceluiași scop precum proprietatea copii, permițând ierarhii multiple în același obiect de configurare. Acești membri permit de asemenea scrierea sub o formă mai compactă a arborelui de configurare.</li><li>proprietatea ID &#8211; dacă w prezentă, oferă baza separării structurii de logică pentru arborii de configurare. Poate fi folosită și pentru a identifica instanțele componentelor.</li></ul><p>Pentru lista completă a membrilor speciali, urmăriți vă rog paragraful următor despre parser-ul JUL.</p><h2>Parser-ul JUL</h2><p>Un parser JUL este o instanță a clasei JUL.UI.Parser folosită pentru a crea un întreg arbore de componente dintr-un arbore de configurare. Procesul de creare instanțiază componentele într-o anumită ordine (ex. de la părinte către copii).<br /> Exemplu:</p><pre class="brush:js">var oParser = new JUL.UI.Parser({
	defaultClass: 'xul',
	useTags: true,
	customFactory: JUL.UI.createDom,
	topDown: true
});</pre><p>Rutina parser-ului acceptă un obiect de configurare ce oferă informația necesară pentru construcția arborelui de componente.<br /> Proprietățile de configurare ale parser-ului sunt:</p><ul><li>classProperty &#8211; numele proprietății clasă în obiectul de configurare &#8211; implicit &#8216;xclass&#8217;.</li><li>defaultClass &#8211; numele clasei implicite dacă numele clasei nu e specificat de către obiectul de configurare &#8211; implicit &#8216;Object&#8217;.</li><li>childrenProperty &#8211; numele proprietății din obiectul de configurare ce conține un vector de obiecte de configurare &#8211; implicit &#8216;children&#8217;.</li><li>membersProperties &#8211; este un vector de nume cu scop similar cu childrenProperty permițând ierarhii multiple sub aceeași configurație părinte &#8211; implicit [].</li><li>IdProperty &#8211; numele proprietății ID a obiectului de configurare &#8211; implicit &#8216;id&#8217;. Permite identificarea componentelor, publicarea lor runtime prin căi de nume specificate și separarea structurii de logică pentru obiectul de configurare.</li><li>bindingProperty &#8211; permite separarea structurii de logică similar cu idProperty dar nu va fi pasată constructorului componentei &#8211; implicit &#8216;cid&#8217;. Nu poate fi folosită pentru identificarea componentei dar oferă o modalitate pentru moștenirea obiectelor incluse &#8211; a se vedea includeProperty.</li><li>topDown &#8211; boolean ce precizează că parser-ul va instanția componentele de sus în jos sau de jos în sus &#8211; implicit false. Pentru procesarea de jos în sus copiii sunt creați mai întâi, iar pentru procesarea de sus în jos părinții sunt creți primii.</li><li>customFactory &#8211; o funcție căreia îi va fi pasat un obiect de configurare. Va fi folosită în loc de constructorul &#8216;new&#8217; &#8211; implicit null.</li><li>parentPropery &#8211; numele proprietății obiectului de configurare căreia îi va fi atribuită automat instanța componentei părinte &#8211; implicit &#8216;parent&#8217;. Este folosită doar pentru instanțierea de sus în jos.</li><li>useTags &#8211; dacă sau nu se utilizează o proprietate tag în loc de classProperty &#8211; implicit false. Pentru limbajele DOM (ex. HTML, XML, SVG, XUL etc.), puteți seta defaultClass la &#8216;html&#8217; de exemplu, iar apoi utiliza proprietatea tag pentru a preciza ce componentă va fi construită.</li><li>tagProperty &#8211; numele proprietății tag pentru a instanția un element DOM &#8211; implicit &#8216;tag&#8217;. JUL.UI are și o funcție specializată numită &#8216;createDom&#8217; pentru a asista la construirea elementelor DOM.</li><li>includeProperty &#8211; permite includerea explicită a altui obiect de configurare în cel curent &#8211; implicit &#8216;include&#8217;. Obiectul curent este aplicat peste obiectul inclus.</li></ul><p>Pentru informații complete despre configurarea oarser-ului, vă rog să consultați topicul aferent din <a title="JUL API Reference" href="https://zonebuilder.github.io/jul/docs/index.html" target="_blank">API Reference </a>.</p><h2>Concluzie</h2><p>Acestea au fost câteva concepte de bază pentru început. Concepte avansate și o serie de tutoriale vor urma.</p> ]]></content:encoded> <wfw:commentRss>http://constructorul-zonal.xhost.ro/concepte-jul/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>