Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    40

    Creazione property automaticamente in custom elements

    Buongiorno a tutti,
    sto cercando di implementare un classe base che deriva da HTMLElement per vari custom element.
    Lo scopo di questa classe è creare in automatico tutte le property e gli attibuti d'appoggio necessaria a lei ed alle classi figlie.
    Per spiegarmi meglio, questo è una parte di codice della classe base:
    codice:
    class Base extends HTMLElement{
       static get observedAttributes() {
          return Object.keys(this.ObservedAttributes);
       }
       // Metodo base per osservare gli attributi su cui si appoggiano le property
       static get ObservedAttributes() {
          let loAttributes  =  {
             "id": {}
          };
          for( let lsPropName in this.PublishedProperties ){
             let lsAttrName =  "data-" + lsPropName.toLowerCase();
             loAttributes[lsAttrName]   =  {
                OnChange: this.PublishedProperties[lsPropName].onChange
             };
          }
          return loAttributes;
       }
       // Metodo base per definire una property
       static get PublishedProperties() {
          return  {
             Visible: {
                help           :  "Property to show/hide object.",
                group          :  "Properties",
                title          :  "Visible",
                type           :  "Boolean",
                defaultValue   :  true,
                isExtended     :  true,
                onChange       :  function( lsAttrName, loOldValue, loNewValue ){
                                     this.style.display   =  Frw.LibMgr.Convert.ToBoolean( loNewValue ) ? "" : "none";
                                  }
             },
             Enabled: {
                help           :  "Property to enable/disable object.",
                group          :  "Properties",
                title          :  "Enabled",
                type           :  "Boolean",
                defaultValue   :  true,
                isExtended     :  true
             }
          };
       }
       attributeChangedCallback( lsAttrName, loOldValue, loNewValue ){
          if( loOldValue !== loNewValue ){
             let loAttributes  =  customElements.get( this.localName ).ObservedAttributes;
             if( loAttributes[lsAttrName].OnChange ){
                loAttributes[lsAttrName].OnChange.apply( this, [lsAttrName, loOldValue, loNewValue] );
             }
          }
       }
       ...
    }

    A questo punto il mio obbiettivo è ciclarmi tutte le published properties della classe e crearle nell'oggetto al momento della creazione, quindi nel costruttore:
    codice:
    class Base extends HTMLElement{
       ...
       constructor(){
          ...
          let loPublishedProp     =  customElements.get( this.localName ).PublishedProperties;
          for( let lsPropName in loPublishedProp ){
             let lfGetter   =  (
                                  function(){
                                     return this.This.dataset[this.PropName];
                                  }
                               ).bind(  {
                                           This     :  this,
                                           PropName :  lsPropName
                                        });
             // DCA setter
             let lfSetter   =  (
                                  function( loValue ){
                                     this.This.dataset[this.PropName] =  loValue;
                                  }
                               ).bind(  {
                                           This     :  this,
                                           PropName :  lsPropName
                                        });
             Object.defineProperty(  this,
                                     lsPropName,
                                     {
                                        configurable   :  true,
                                        enumerable     :  true,
                                        get            :  lfGetter,
                                        set            :  lfSetter
                                     });
          }
          ...
       }
       ...
    }

    Il giro funziona senza problemi. Il problema arriva quando voglio dichiarare la published property ( PublishedProperties mi serve anche come help ) in modo che venga creato anche in automatico l'attributo da osservare, ma la property vera e proprio voglio implementarmela da me:
    codice:
    class Base extends HTMLElement{
       ...
       get Visible(){
          return true;
       }
       set Visible(){ }
       ...
    }

    In questo caso, la property Visible non mi deve essere generata in automatico, ma deve mantenere la mia implementazione.
    Ho provato questa soluzione ma senza risultato:
    codice:
    class Base extends HTMLElement{
       ...
       constructor(){
          ...
          let loPublishedProp     =  customElements.get( this.localName ).PublishedProperties;
          for( let lsPropName in loPublishedProp ){
             if( !this.hasOwnProperty( lsPropName ) ){
                let lfGetter   =  (
                                     function(){
                                        return this.This.dataset[this.PropName];
                                     }
                                  ).bind(  {
                                              This     :  this,
                                              PropName :  lsPropName
                                           });
                // DCA setter
                let lfSetter   =  (
                                     function( loValue ){
                                        this.This.dataset[this.PropName] =  loValue;
                                     }
                                  ).bind(  {
                                              This     :  this,
                                              PropName :  lsPropName
                                           });
                Object.defineProperty(  this,
                                        lsPropName,
                                        {
                                           configurable   :  true,
                                           enumerable     :  true,
                                           get            :  lfGetter,
                                           set            :  lfSetter
                                        });
             }
          }
          ...
       }
       get Visible(){
          return true;
       }
       set Visible( lbValue ){
       }
       ...
    }

    Come posso fare quindi per sapere se la mia istanza di oggetto ha già o no la property che sto per creare?
    Grazie a tutti
    Il bello dei computer è che puoi programmarli e saprai sempre cosa aspettarti. Non come le persone.
    Il bello delle persone è che non ti annoierai mai perchè non saprai mai cosa aspettarti. Non come i computer.

  2. #2
    Moderatore di Annunci siti web, Offro lavoro/collaborazione, Cerco lavoro L'avatar di cavicchiandrea
    Registrato dal
    Aug 2001
    Messaggi
    28,467
    Sicuro sia javascript ?
    Cavicchi Andrea
    Problemi con javascript, jquery, ajax clicca qui

  3. #3
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    40
    Ciao cavicchiandrea,
    sì, ne sono certo. Utilizzo la sintassi per le classi introdotta in ES6.
    Il bello dei computer è che puoi programmarli e saprai sempre cosa aspettarti. Non come le persone.
    Il bello delle persone è che non ti annoierai mai perchè non saprai mai cosa aspettarti. Non come i computer.

  4. #4
    Moderatore di Annunci siti web, Offro lavoro/collaborazione, Cerco lavoro L'avatar di cavicchiandrea
    Registrato dal
    Aug 2001
    Messaggi
    28,467
    Pertanto è una sintassi specifica per ie o funzione su tutti i browser? Perché non l'avevo mai vista fin'ora.
    Cavicchi Andrea
    Problemi con javascript, jquery, ajax clicca qui

  5. #5
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    40
    Mi sono spiegato male, per ES6 non intendo internet explorer ma ECMAScript 6. Funziona sui browser più recenti ( Chrome, Safari, Opera, Firefox... Non ho testato Edge ). Nel mio caso, non essendo un sito web vero e proprio ma un'interfaccia che gira su un iis locale, non è importante il supporto browser ed utilizzo l'ultima versione Chrome.
    Il bello dei computer è che puoi programmarli e saprai sempre cosa aspettarti. Non come le persone.
    Il bello delle persone è che non ti annoierai mai perchè non saprai mai cosa aspettarti. Non come i computer.

  6. #6
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    40
    Sono riuscito a risolvere il problema implementando nella classe padre questo metodo:
    codice:
    class HTMLFrwBase extends HTMLElement {
       ...
       HasOwnProperty( lsPropName ){
          // init var
          let lbHasOwnProperty =  false;
          // starting point
          let loProto =  Object.getPrototypeOf( this );
          // while not found and not HTMLElement base class
          do{
             // get property definition
             let loPropDef  =  Object.getOwnPropertyDescriptor( loProto, lsPropName );
             // check if has property
             lbHasOwnProperty  =  loPropDef !== undefined && loPropDef !== null;
             // get prototype of actual prototype
             loProto  =  Object.getPrototypeOf( loProto );
          }
          while( !lbHasOwnProperty && loProto.constructor.name != "HTMLElement" && loProto !== null );
          // return if found
          return lbHasOwnProperty;
       }
       ...
    }

    Ho modificato poi il ciclo nel costruttore come segue:
    codice:
    class Base extends HTMLElement{
       ...
       constructor(){
          ...
          let loPublishedProp     =  customElements.get( this.localName ).PublishedProperties;
          for( let lsPropName in loPublishedProp ){
             if( !this.HasOwnProperty( lsPropName ) ){
                let lfGetter   =  (
                                     function(){
                                        return this.This.dataset[this.PropName];
                                     }
                                  ).bind(  {
                                              This     :  this,
                                              PropName :  lsPropName
                                           });
                // DCA setter
                let lfSetter   =  (
                                     function( loValue ){
                                        this.This.dataset[this.PropName] =  loValue;
                                     }
                                  ).bind(  {
                                              This     :  this,
                                              PropName :  lsPropName
                                           });
                Object.defineProperty(  this,
                                        lsPropName,
                                        {
                                           configurable   :  true,
                                           enumerable     :  true,
                                           get            :  lfGetter,
                                           set            :  lfSetter
                                        });
             }
          }
          ...
       }
       ...
    }
    Il bello dei computer è che puoi programmarli e saprai sempre cosa aspettarti. Non come le persone.
    Il bello delle persone è che non ti annoierai mai perchè non saprai mai cosa aspettarti. Non come i computer.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2019 vBulletin Solutions, Inc. All rights reserved.