Widget Разширяване "MakeNode"

8 юли 2011 г. в 2:11 ч. от Satyam | в развитието | 6 Коментари

Бележка на редактора: Тъй като тази статия е публикувана, модула MakeNode е бил публикуван, за да Галерия Юи и получи някои подобрения. Моля, обърнете се към актуализираната статия, Актуализирано: Widget "MakeNode", Удължаване .

В предишната ми статия, рецепта за 3 Заявление Юи , показах начин за използване на Y.substitute като един много основен шаблон процесор. Идеята отнел живота от там, с предложения от хора в IRC канал # Юи, и аз направих една Widget разширение, което е на разположение на моя сайт, наречен MakeNode . MakeNode не е родово процесор шаблон и не се разбира като едно цяло. От друга страна, тя е тясно интегриран с Юи Widget фондация клас, включително клас и събитие помощници и интернационализация. В тази статия, аз ще се на Spinner например и да го променят, за да следват насоките от предишната ми статия и да използват MakeNode. Модифицираният на Spinner компонент ( JS , CSS , спрайтове ), както и един пример от моя сайт. Връзки към допълнителни ресурси могат да бъдат намерени в края на тази статия.

Разширяване компоненти

След MakeNode е заредена, вие трябва да се включи модул си YUI().use() изявление с името 'makenode' . Тогава, за разширяване на обсега на джаджата, да я списъка в третия аргумент Y.Base.create() , като този:

  Y.Spinner = Y.Base.create (
      "Spinner",
      Y.Widget,
      [Y.MakeNode],
      {
         / / Например членовете на ...
      }
      {
          / / Статични членове
      }
 ); 

Можете да добавите MakeNode заедно произволен брой подходящи разширения за джаджа, като WidgetParent, WidgetChild, WidgetStdMode и др. MakeNode добавя две-защитени методи, _makeNode и _locateNodes, и той ще прочете от няколко статични свойства, ако се открие.

Всички членове на това разширение са защитени или частни, тъй като те са предназначени да бъдат използвани от разработчик на компонента, а не от ОСЪЩЕСТВЯВАЩА използването на тези компоненти, които не трябва да се занимава с тях.

Дефиниране на шаблон

Първото нещо, което ще правите обикновено е да се определят шаблона за вашия компонент. За на Spinner нашата шаблон ще бъде:

  _TEMPLATE:
     "<input Type="text" title="{s input}" class="{c на input}">",
     "<button Type="button" title="{s up}" class="{c up}"> </ бутон> ',
     "<button Type="button" title="{s down}" class="{c down}"> </ бутон> '
 ]. Се присъединят ('\ n'), 

Шаблонът по подразбиране обикновено ще бъде назован _TEMPLATE и декларирани по другите статични свойства на класа, като ATTRS . MakeNode ще използвате този шаблон, ако никой друг не е изрично предвидено. Шаблонът е изработен от обикновен HTML плюс серия на контейнери, затворени в къдрави скоби, изработени от един символ (преработка код) и последван от един или повече аргументи. Контейнери и това, което произвеждат, са:

  • {@ attributeName} конфигурация атрибут стойност

  • {p propertyName} например стойността на имота

  • {m methodName arg1 arg2 ….} връщаната стойност на даден метод. Обработката код е последвано от метода име и произволен брой аргументи, разделени с интервал. Strings трябва да бъде затворен в двойни кавички. Номера, Булев тип и null ще бъдат преобразувани от низ към своите собствени типове данни

  • {c classNameKey} CSS име на класа, генерирани от на статично собственост на _CLASS_NAMES

  • {s key} низ от атрибут на strings , използвайки key , тъй като под-атрибут.

  • {? other placeholder } произвежда низ checked когато в резултат на обработката на останалата част от контейнера е вярно.

  • {} друга стойност, ще бъдат обработени точно като Y.substitute прави.

Например, {@ value} ще превежда към this.get('value') докато {p value} превежда this['value'] .

{m} контейнер е малко по-сложна. Първият аргумент след по m обработка код е името на метода и на останалата част от аргументите, всички, разделени с интервал, които ще бъдат предадени на даден метод. Тези аргументи могат да бъдат числа, null , true , false или низове, заградени в двойни кавички. Ще ги анализира MakeNode и да ги конвертирате своите собствени видове, като по този начин {m myMethod 123.45 true “this is a string”} ще доведе до, призовава this.myMethod(123.45, true, “this is a string”) така че първите два аргумента се превръща в тяхното правилно типове данни и низ може да съдържа интервали. За да включите двойни кавички, използвайте \\" , двойно обратно наклонена черта се изисква, тъй като JavaScript ще тълкуване на един и да го изхвърля, преди да стане да MakeNode. Само двойни кавички са позволени, MakeNode не използва eval() така че парсера се ограничава но безопасно. всичко друго, но не числа, null , Булев тип и двойни низове в кавички, ще бъдат игнорирани.

{?} контейнер е удобно да се използва с отметки и радио бутони. Тя ще произведе низ “checked” в зависимост от истинната стойност на инструкция за обработка код, който следва. Така <input type=”checkbox” {? m getLength}/> <input type=”checkbox” {? m getLength}/> ще произвежда значително отметка, ако getLength метод връща всичко друго, но нула. {?} ще приеме някое от другите контейнери, въпреки че тя има смисъл само с първите три.

За {c} контейнер, ние трябва да имат определени _CLASS_NAMES собственост.

Допълнителни контейнери могат да се добавят да MakeNode като ги добавите в _templateHandlers хеш.

_CLASS_NAMES Собственост

Заедно с ATTRS и _TEMPLATE статични качества, можем да определят едно _CLASS_NAMES собственост, която сочи към масив от низове. Всяка от тези струни ще бъдат използвани за генериране на име на класа. Така _CLASS_NAMES: ['input'] ще произвежда име на класа “yui3-spinner-input” . И Тези classNames се съхраняват в инстанция собственост this._classNames . {c input} контейнер в шаблона по-горе, ще бъде заменен от “yui3-spinner-input” .

Можете да използвате на _CLASS_NAMES собственост, за да генерира произволен брой classNames, дали да ги използвате в шаблон или не. Вие все още може да достигне до тези допълнителни classNames в рамките this._classNames . Име на класа се генерира на yui3 представка, следвана от стойността на NAME статично собственост, се обърна с малки букви, а след това на низ в _CLASS_NAMES (този, последният не ще се превърнат в малки букви), разделени с тирета. _classNames хеш също така ще съдържа на classNames за boundingBox и contentBox , първо под "." ключ и на второ място във “content” . Widget възлага на boundingBox classNames, получени от стойностите на NAME собственост на всеки от класовете в наследството верига, започвайки с yui3-widget . MakeNode магазини в this._classNames само най-отгоре на клас на boundingBox .

Ако компонент е на няколко нива, далеч от Widget, като SuperSpecialSpinner наследи от SuperSpinner която се наследява от Spinner който наследява Widget, и, ако някой или всички от тях имат _CLASS_NAMES свойства определени, MakeNode ще произвежда classNames за всички тях и да ги съхранявате в this._classNames . Не е нужно да се включи на всяко ниво, имената, които вече са обявени в предишните нива. В действителност, тя е по-добре, че не, тъй като classNames, произведени на всяко ниво ще използва стойността на NAME на това ниво. Така, в SuperSpecialSpinner , {c input} все пак ще доведе до “yui3-spinner-input” и не “yui3-superspecialspinner-input” и така тя ще продължи да ви CSS файл все още валидни.

{} Контейнер

Widget има strings конфигурация, определени атрибут, въпреки че не се инициализира с никаква стойност. Този атрибут е предназначена да държи на низове, които се виждат (или чрез екранни четци, прочетете) потребителят. Важно е, че никога няма да са видими струни директно в шаблона. Това не е изискване на MakeNode - никога не е била добра идея изобщо. Всички низове, които трябва да бъдат разглеждани или да прочетете на потребителя, трябва да винаги да се поставят в strings атрибут. strings атрибут съдържа хеш, където се намира всеки отделен текст от ключовата му. Spinner компонент има следните низове, които можете да видите, използвани в шаблона по-горе.

  низове: {
     стойност: {
         вход: "Натиснете стрелката нагоре / надолу за малки стъпки, страница нагоре / надолу за големи стъпки."
         нагоре: инкрементирате ",
         надолу: "Декремент"
     }
 } 

Най-добрата част за това е, че компонентите могат да бъдат локализирани на други езици много лесно от разработчиците, които използват компоненти. При създаването на копие на Spinner, можете да направите:

  Var mySpinner = нов Spinner ({низове: Y.Intl.get (Spinner ')}); 

Настройка на конфигурационните атрибут strings по този начин замества стандартните strings стойности с тези от езиковия файл ресурс, с помощта на предварително дефинирани език. {s} контейнер достъп до струните, които се съхраняват в strings атрибут, нито подразбиране или преведените, ако е зададено. {s xxxx} контейнер, в действителност, е нищо повече от един пряк път към {@ strings.xxxx} контейнер. Въпреки това, първото може само достъп до струните на най-високо ниво, като например, {@ strings.xxxx.yyyy.zzzz} ще ви даде достъп до низ дълбоко надолу.

Използването на _makeNode в renderUI

Ние използваме шаблон за създаване на маркиране за нашия компонент. За да направите това, ние можем да се обадите метод на MakeNode на _makeNode , като този:

  renderUI: функция () {
     . this.get ("contentBox"), добавяне (this._makeNode ());
 } 

Това ще запълни в на contentBox на нашата джаджа с маркиране от обработката на шаблона. _makeNode метод връща инстанция на Y.Node които могат да бъдат прикрепени или се добавя никъде или просто се държат по-късна употреба. Той не се връща низ, тя произвежда една Node например.

_makeNode метод отнема два незадължителни аргумента: справка за шаблон и обект, за да попълните в контейнери,, като Y.substitute . В нашия прост пример Spinner има един шаблон за цялата джаджа, но други джунджурии може да изисква от битове и парчета, направени от няколко шаблона. В този случай, обикновено наричаме _makeNode без аргументи за основната част и отново го наричат ​​с различни шаблони, за да попълните в допълнителните части. Примерът съдържа този renderUI метод:

  renderUI: функция () {
     VAR fieldset = this._makeNode ();
     this.each (функция (елемент) {
         fieldset.appendChild (this._makeNode (MultipleTemplates.RADIO_TEMPLATE, т.));
     });
     this.get ("contentBox"), добавяне (fieldset).
 } 

Първата покана към _makeNode връща Node например, се съхранява в променливата fieldset . Пробата компонент, също се удължава с Y.ArrayList така че RADIO_TEMPLATE ще бъде изпълнен със стойности, взети от предмети, съхранявани в списъка на масива и възли, приложени към fieldset преди тя да бъде най-накрая приложени към contentBox . Специални контейнери, като например {@} или {p} все още ще се отнасят за качества или свойства в основния обект. Вложените елементи ще бъдат обработвани точно както Y.substitute би.

Метод _locateNodes

MakeNode предвижда по-нататък, метода една _locateNodes който ще се опита да намерите всички елементи с на classNames декларирани в _CLASS_NAMES . За да намерите конкретни елементи, които могат да преминат произволен брой ключове за име на класа, в противен случай, _locateNodes опитва всички тях. За всеки елемент намерени на всеки име на класа, _locateNodes ще произвежда частна собственост например с помощта на долна представка, следвана от ключовото име и суфикс “Node” . Така в нашия Spinner например, _locateNodes ще генерира на имоти _inputNode , _upNode и _downNode . Ако няколко елемента имат едно и също име на класа, _locateNodes ще се върне препратка към първия от тях. Ако един елемент не е намерен, не променлива ще бъде създаден.

, На Spinner компонент ние използваме _locateNodes след създаването на маркиране:

  renderUI: функция () {
     this.get (CBX) добавяне (this._makeNode ());
     this._locateNodes ();
 } 

_EVENTS Статичен собственост

Още едно свойство може да бъде определен по линиите на _TEMPLATE и _CLASS_NAMES и че е _EVENTS . _EVENTS ще съдържа хеш на ключове името на класа, всяка от които съдържа хеш на събитието видовете и начините да се справиш с тях. Тя е по-добре да се обясни с пример:

  _EVENTS: {
     '.': {
         ключ: {
             Fn: _onDirectionKey ",
             аргументи: ((Y.UA.opera) "надолу": "Press:") + "38, 40, 33, 34"
         }
         mousedown: "_onMouseDown"
     }
     "...": {
         mouseup: "_onDocMouseUp"
     }
     вход: {
         промяна: "_onInputChange"
     }
 } 

_EVENTS е обект (хеш), с произволен брой свойства. Имената на имотите, което означава, че ключовете на хеша, да идентифицира елементите, чиито събития, ние ще слушате. Те са същите идентификатори, използвани в _CLASS_NAMES . Има две допълнителни специални клавиши "." и ".." . Докато клавишите на име на класа се отнасят за елементи, вложени в рамките на contentBox "." Ключът се отнася до на boundingBox себе си, докато ".." се отнася до документ, съдържащ тази джаджа. Мислете за тях като прави chdir команда, когато се намира в boundingBox ниво. _EVENTS собственост се обработват, след методи renderUI , bindUI и syncUI са били наричани така че джаджа се очаква да вече да е поставена в тялото на документа, в противен случай ще се провали. ".."

Всеки един от записите в _EVENTS е един допълнително обект, че използвате вида на събитието като си ключ и името на един метод, например да се справя. _EVENTS , е статична променлива, има никакъв достъп към this , така че тя не може да вземе действителните препратки функция, само името на метода на събитие слушател. Някои типове събития се нуждаят от допълнителни аргументи, като key събитие. В този случай, вместо за предоставяне на името на събитието манипулатор може да осигури един обект с имоти fn и args да държи на името на функцията и допълнителни аргументи, когато е необходимо.

MakeNode ще използва Node.delegate да слушате събитията на вложените елементи, докато ще използва Y.on да слушате на събития от boundingBox и тялото на документа. (Забележка: слушане на key събитие на всеки вложен елемент работи само с на версия 3.4.0pr1 и повече, тъй като делегацията на key . събитието не бе на разположение преди всички други функции, работят с предишните версии, както и)

_EVENTS декларации са кумулативни,, когато компоненти наследи една от друга. Всеки клас в наследството верига ще има своя _EVENTS декларация обработват отделно.

_ATTRS_2_UI Статичен собственост

Събития вървят в двете посоки, от потребителския интерфейс на компонента и от компонент на потребителския интерфейс. Първият се обработват от _EVENTS собственост. Тогава там са събитията, уволнен от промени в стойността на атрибут, които трябва да бъдат отразени в потребителския интерфейс. Както споменах и в предходния член, когато има някакви вторични ефекти от промяна на конфигурацията атрибут, те трябва да се обработват от слушателите на климата събития, а не от допълнителен на setter метод на атрибута, което трябва да се занимават само с нормализиране на стойността се определя. Потребителският интерфейс трябва да отразяват състоянието на конфигурационните атрибути, на първо място в syncUI , когато се инициализира и след това на всеки случай на промяна на атрибут. За последното, ние трябва да се приложи слушател събитие, което ние правим в bindUI . Widget вече предвижда механизъм, който да прави толкова просто, който описах в коментарите към предишната статия.

Widget използва инстанция на собственост _UI_ATTRS който съдържа един обект с два допълнителни свойства SYNC Синхронизация и BIND . Всяка от тях е масив списък на имената на конфигурационните атрибути, които трябва да бъдат първоначално synched и след това слушах, за да запази потребителския интерфейс, който отразява текущите стойности. Widget очаква всеки един от тези записи, за да има метод, свързан с него, на име след име на атрибут,, представка от _uiSet с първия знак от името на атрибута, конвертирани с главни букви името на метода в правилното камила случай. Така, ако "value" , посочени в някоя от масиви на _UI_ATTRS или SYNC или BIND ), Widget да се очаква да се намери метод _uiSetValue . Този метод ще получите два аргумента, value се определя и src на промяната. Това е кодът за нашия Spinner _uiSetValue метод:

  _uiSetValue: функцията (стойност, SRC) {
     ако (SRC === UI) {
         се върне;
     }
     this._inputNode.set (стойност, this.get (форматиране) (стойност));
 } 

Всички главни идентификатори, които виждате в тази част от кода съответстват на низови константи, обявени на друго място, за да позволи на Юи компресор, за да си свърши работата по-добре. Методът, по същество, определя value HTML атрибут в <input> кутия за нов набор стойност, след като е бил форматиран. Позоваването на текстовото поле е предоставена от _locateNodes . src аргумент първоначално се проверяват, за да видите, ако на низовата стойност 'ui' . Ако това е така, да не се предприемат действия ще бъдат предприети. Това е, за да се избегне безкрайното електрически вериги. Ако потребителят въведе нещо в полето за въвеждане, нейната стойност ще отиде в value атрибут конфигурация, която след това ще огън, едно valueChange събитие, което би се _uiSetValue призовани, които, ако не бъдат, тогава ще отида и да промените стойността на полето за въвеждане, които ще предизвика отново целия процес. Така в _uiSetValue , ако знаем, промяната идва от потребителския интерфейс, което правим нищо и така се прекъсне веригата. Това обаче изисква друга част от кода на друго място. В слушател за събитието DOM, когато ние поставихме конфигурация атрибут, ние използваме третия допълнителен аргумент да се определят, като това:

  _afterValueChange: функция (EV) {
     this.set (VALUE, ev.newVal {SRC: UI});
 } 

Това е за нас, за да се гарантира, че промените, идващи от потребителския интерфейс са маркирани по този начин и след това да се провери дали едно и също знаме, за да се избегне примки.

С всичко това каза, аз не са все още споменава статичен собственост _ATTRS_2_UI , посочени в заглавието на този раздел. Тъй като коментарите в предишните ми показва статия (чрез гафове, направени в тях), като се уверите, че са надлежно описани всички атрибути, които оказват влияние върху потребителския интерфейс е малко разхвърлян. Никога не трябва да се инициализира _UI_ATTRS от нулата, тъй като Widget вече са изброени един куп от атрибути, както и тези, които ще бъдат загубени. Трябва да се слеят нови имена на атрибут над съществуващите, което е малко трудно да си спомните как да го направя така. За да го прости, MakeNode ще прочетете от статично собственост _ATTRS_2_UI и че конкатенация за вас. Тя ще слеят всички тези списъци от всеки клас в наследството верига, така че на всяко ниво всеки клас могат да се справят собствените си качества. В Spinner, имаме:

  _ATTRS_2_UI: {
     BIND: стойност,
     Sync: стойност
 } 

MakeNode ще приеме набор от имена, или едно име на атрибут, тъй като в този случай.

Естествено възниква въпросът, защо два списъка, за да обвърже за синхронизиране? Доста често на SYNC масив има по-малко допълнения от списъка на BIND и това е, защото шаблона за компонент може би вече имат почти същата стойност по подразбиране, като атрибут на конфигурацията и там е необходимо да се прави първоначален синхронизиране. Така че, ако стойността по подразбиране за value на атрибут конфигурация е празен низ и елемент на <input> в шаблона има никаква value атрибут, а след това там не е необходимо да ги синхронизира от инициализация.

MakeNode ще проверява за дублирани записи в някоя от тези масиви. Ако някоя се появи, това означава, че един клас нашия компонент наследява вече обработва този атрибут и всяка нова декларация, най-вероятно прекрачи _uiSetXxxx манипулатор за него. Между другото, MakeNode също проверява за дублирани записи в _CLASS_NAMES , които също могат да предизвикат конфликт в някои, макар и не всички, обстоятелства. MakeNode ще напишете съобщение до дневника за всяка такава грешка.

Заключение

MakeNode осигурява много прост шаблон на процесор, с проста функционалност, която е силно обвързана с класа Widget фондация. Той също така предвижда помощни методи, да създават classNames, да бъдат използвани в шаблона и да използват тези имена, за да се локализират, създадени възли. Той също така предоставя средства, за да кука в събитията, породени както от потребителския интерфейс и самия компонент и се сдружават с метод. Той прави всички тези неща, докато се грижи за спазване на веригата наследство направо до притурка и всяко ниво на класове, които могат да въведат уточнения.

То не съдържа абсолютно всички възможности, но обхваща добър набор от тях. Въпреки това, не ви лишава от добавяне на допълнителна функционалност. Рядко може да се наложи да пиша метод един bindUI или syncUI ако използвате лепило, предоставена от MakeNode, но можете да го направите,, тъй MakeNode не ги използва.

Като бонус на тези, които имаха търпението да четат толкова далеч, аз също са променени Антъни малко пръстено гърне на бутона набор от компоненти за галерия:

API документи могат да бъдат намерени тук .

Споделете и разширяване : Запазете си отметка към del.icio.us | Digg тя | Reddit!

6 Коментари »

RSS емисия за коментари по тази публикация TrackBack URI

  1. Дали това е съвместим с Изглед компонент на нови MVC Райън идва в 3.4.x? Може да се използва, за да оказват на маркиране по начин, съвместим с тази рамка?

    Коментар от Андрю Wooldridge - 9 юли, 2011 #

  2. Андрю ,

    Това разширение е предназначен като помощник за изграждане на компоненти, като Бътън и Spinner примери показват, не за изграждане на цели приложения, като MVC рамка. Тези компоненти могат да се използват навсякъде, всеки друг компонент, получен от Widget. В рамките на MVC, то би било естествено да се използват такива компоненти в класове, наследяващи от Y.View до изграждане на потребителския интерфейс, заедно обикновен HTML или друг компонент, получен от Widget, дали тя използва MakeNode или не.

    Коментар от Satyam - 10 юли, 2011 #

  3. Satyam,

    Това е доста голяма! Преживявал съм всички болезнени точки, които се занимаваме с тази джаджа разширение. Изглежда, че използването на това разширение може да премахне много от повтарящи се доктрина код, завършва писмена форма, когато създаване на потребителски Джаджи, докато стандартизиране за това как да се свържете кода и логика с DOM и рендиране, което е вълнуващо да видим!

    Ще се това да се добави към Юи 3 Галерия, което прави по-достъпни за хората да използвайте ()?

    Подобно на Андрю посочи има някои концептуални припокриване с Y.View за събития и оказване, въпреки че двата API, са различни. Може би си заслужава да разберете, ако има обща почва за двете АПИС, за да бъде по-сходна (по-специално с DOM събития неща).

    От гледна точка на цялостния API сте направили всичко, което е защитена / частни чрез "_" (долна черта) префикс, аз съм любопитен да чуя вашите мисли по този въпрос. Чувствам, че статичните свойства като: "_CLASS_NAMES", и "_EVENTS` и т.н. може и да бъде само: "CLASS_NAMES` и `СЪБИТИЯ" без долна префикс. Тя може да бъде само моето предпочитание, но тя се чувства прекалено защитно :)

    Коментар от Ерик Ferraiuolo - 12 юли, 2011 #

  4. Ерик ,

    Благодаря ви за вашия коментар. Всъщност, това е роден на скучно повторение. Аз също харесвам стегнатост на компонент, като част от него се разглеждат в декларативните начини и процесуалното неща се намалява и стандартизирани, специално всички _uiSetXxxx, методи.

    Аз не искам да се справят с GitHub и Юи Галерия така че няма да го качи там. Нямам нищо против, ако някой, но аз няма да го направя или да го поддържа.

    DOM събитие, което идва точно, на Y.View, с изключение на това, че аз използвам classNames ключовете, за да се идентифицират елементите, тъй като цялото удължаване прави, добре, широко използване на тях. Тя също се занимава с кука събития в цялата йерархия на класа, така че не е нужно да се повтарят тези, когато наследява от други класове.

    Що се отнася до защитените / частни членове, вдигнах това с Джени, който пожела на екипа и смениха всички бивши публична защитени тези, базирани на този съвет.

    По принцип, има две роли на разработчиците, компонентът, създател и потребител компонент или "изпълнител", като Джени е позовал на тях. По-добре е, ако членове на клас, предназначени за компонент разработчик не се претрупва API Документи за на изпълнител. В този смисъл, много от членовете на джаджа като CONTENT_TEMPLATE, renderUI, HTML_PARSER или Base.ATTRS, никога не трябва да е публично, като изпълнител не трябва дори да знаят за тях.

    От друга страна, членове, като например _uiSetTabIndex или _uiSetDisabled са много правилно деклариран като защитени. Така, в режим на разработчик на компонент, вие винаги трябва да има Покажи защитени на, а като изпълнител, което не трябва. Това би предотвратило компоненти разработчиците от-прилагане на функционалност, която вече е там, като първоначалния компонент на бутон в галерия, които са имали код redoing това, което вече правят тези два метода.

    Предполагам, че тъй като Джени трябваше да го донесе на отбора, няма насоки в това отношение и по този начин ние ще трябва да живее с известна непоследователност в съществуващи компоненти.

    Коментар от Satyam - 12 юли, 2011 #

  5. Актуализация:

    Добави още една обработка код: "1". Тя е полезна в работата с текст единствено / множествено число, например: {P Количество} {1 {стр. Количество}. "Единица" "единици"}. Този низ ще произвежда или "1 единица" или "123 единици, в зависимост от стойността на имота Количество.

    Както е показано в примера по-горе, контейнерите могат да бъдат вложени една в друга. По този начин, аргументът на контейнер може да бъде върната стойност от друг контейнер.

    Аз също се промени в контейнера да действа повече като {}:? Оператор. Вместо да произвежда определен текст, тя позволява да се върне всичко, своите аргументи, например: {? {P Количество} {P Количество} "никой"}.

    Като краен пример, този шаблон:

    {? {P Количество} "{P Количество} {1 {стр. Количество}." Единица "" единици "}" "None"}

    ще произвежда текста "никой", "1 единица", "2 единици", "3 единици" и така за последователните стойности на имота Количество.

    Методът за преработка на шаблон сега е на разположение като метод _substitute,.

    Коментар от Satyam - 13 август, 2011 #

  6. Допълнителни промени:

    Сега, _EVENTS статичен собственост, хеш, определящи слушателите за всяко събитие, отнема няколко допълнителни виртуални селектори. Структурата на _EVENTS е:


    _EVENTS: {
    selector: {
    eventType: listener,
    ....
    }
    }

    селектори са ключовете, използвани в собственост _CLASS_NAMES, за да се създаде classNames, използвани в шаблоните на HTML елементи, които помагат ги намерите.

    Имаше две специални селектори: "." показва boundingBox и ".." документ джаджа е.

    Сега съм добавил два други виртуални селектори, това, всички главни, се отнася до самата джаджа и Y до Y инстанция, например:


    _EVENTS: {
    THIS: {
    visibleChange: '_afterVisibleChange'
    },
    Y: {
    'broadcastingWidget:somethingChange':'_afterSomethingChange'
    }
    }

    Ключът Y, въпреки че тя има за цел да представлява например Y, ще бъдат взети от JavaScript низ "Y". Винаги използвайте Y като виртуалната ключ, дори и ако сте се обадили Юи например нещо друго, не забравяйте, това е просто низ "Y", а не от Y, например.

    MakeNode ще определят само след събитието слушателите, никога преди (на) плеъри, които е най-честият случай. Ако имате нужда да слушате "преди" събитието, както обикновено.

    Коментар от Satyam - 19 август, 2011 #

Оставете коментар

Забележка: Коментари са модерирани за първи таймери. Спам заличават.

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Поместено от Yahoo!

Copyright © 2006-2012 Yahoo! Inc. Всички права запазени. Декларация за поверителност - Условия за ползване

Осъществено от WordPress на Yahoo! Уеб хостинг .