2010-04-28 28 views
11

me han hecho algunas investigaciones sobre el foro ExtJS respecto métodos privados y campos dentro de una clase extendida , y no pude encontrar ninguna respuesta real a esta.al extender una clase usando ExtJS

y cuando digo una clase extendida quiero decir algo como esto:

Ext.ux.MyExtendedClass = Ext.extend(Ext.util.Observable, { 
    publicVar1: 'Variable visible from outside this class', 
    constructor: function(config) { this.addEvents("fired"); this.listeners = config.listeners; }, // to show that I need to use the base class 
    publicMethod1: function() { return 'Method which can be called form everywhere'; }, 
    publicMethod2: function() { return this.publicMethod1() + ' and ' + this.publicVar1; } // to show how to access the members from inside another member 
}); 

El problema aquí es que todo es público. Entonces, ¿cómo agrego una nueva variable o método dentro del alcance de MyExtendedClass que no se puede acceder desde el exterior pero se puede acceder mediante los métodos públicos?

Respuesta

4

Uso algo como lo siguiente.

var toolbarClass = Ext.extend(Ext.Container, 
    { 
    /** 
    * constructor (public) 
    */ 
    constructor: function(config) 
    { 
     config = config || {}; 

     // PRIVATE MEMBER DATA ======================================== 
     var accountId = Ext.id(null, 'ls-accountDiv-'); 

     // PUBLIC METHODS ======================================== 
     this.somePublicMethod = function(){ 
     console.log(accountId); 
     }; 

... 
+0

+1 ¡Funciona! Pero acabo de darme cuenta de que hay otra solución que parece mejor. Porque con su solución, el tiempo de creación de cada instancia aumentará, y creo que el mío no. Voy a publicarlo ahora, para que la gente pueda decir si estoy equivocado o no. –

+5

Doy la bienvenida a esta conversación. Podría decirse que muy pocos desarrolladores están preocupados por la ocultación de datos al desarrollar en JavaScript. – Upperstage

23

El siguiente ejemplo muestra el Upper Stage way para definir & privilegiados miembros públicos privados. Pero también muestra cómo definir miembros estáticos privados (también llamado miembros de la clase), y miembros públicos no privilegiados. El uso de estos últimos 2 en lugar de los privilegiados, que reducirá el tiempo de inicialización, ya que no se analizan cada vez que se crea un nuevo objeto de su clase:

Ext.ux.MyExtendedClass = Ext.extend(Ext.util.Observable, 
 
    (function() { 
 
    // private static fields (can access only to scope: minimum privileges). 
 
    var privStaticVar = 0; 
 
    // private static functions (can access only to scope and arguments, but we can send them the scope by param) 
 
    var privateFunc1 = function(me) { return me.name + ' -> ClassVar:' + privStaticVar; }; 
 
    var privateFunc2 = function(me) { return me.publicMethod1() + ' InstanceVar:' + me.getPrivateVar(); }; 
 
    return { 
 
     constructor: function(config) { 
 
     // privileged private/public members (can access to anything private and public) 
 
     var privateVar = config.v || 0; 
 
     var privInstFunc = function() { privateVar += 1; }; 
 
     this.name = config.name; 
 
     this.incVariables = function(){ privInstFunc(); privStaticVar += 1; }; 
 
     this.getPrivateVar = function(){ return privateVar; }; 
 
     }, 
 
     // public members (can access to public and private static, but not to the members defined in the constructor) 
 
     publicMethod1: function() { this.incVariables(); return privateFunc1(this); }, 
 
     publicMethod2: function() { return privateFunc2(this); } 
 
    }; 
 
    }()) 
 
); 
 

 
function test() { 
 
    var o1 = new Ext.ux.MyExtendedClass({name: 'o1', v: 0}); 
 
    var o2 = new Ext.ux.MyExtendedClass({name: 'o2', v: 10}); 
 
    var s = o1.publicMethod2() + '<br>' + o1.publicMethod2() + '<br><br>' + o2.publicMethod2() + '<br>' + o2.publicMethod2(); 
 
    Ext.get("output").update(s); 
 
}
<link href="//cdnjs.cloudflare.com/ajax/libs/extjs/3.4.1-1/resources/css/ext-all.css" rel="stylesheet"/> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/extjs/3.4.1-1/adapter/ext/ext-base.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/extjs/3.4.1-1/ext-all.js"></script> 
 

 
<p>Click the button to instantiate 2 objects and call each object 2 times:</p> 
 

 
<button onclick="test();">Test</button> 
 

 
<p>You can click the button again to repeat. You'll see that the static variable keep increasing its value.</p> 
 

 
<p>&nbsp;</p> 
 
<div id="output"></div>

+4

esto se conoce comúnmente como Patrón de Módulo, puede encontrarlo escrito en el blog de YUI – seanmonstar

+1

Estoy convencido de que * privStaticVar *, * privateFunc1 * y * privateFunc2 * se analizarán solo una vez (y con las pruebas que realicé) obtuvo los resultados correctos). Porque la palabra clave 'new' no afectará a los miembros de este patrón de módulo, ya que se analizan mientras se ejecuta Ext.extend (mucho antes de que el constructor o cualquier otro método entre en escena). Además, los patrones de módulos son singletons, así que creo que eso también lo explicaría. –

+0

Estoy de acuerdo; perdón por el comentario anterior. – Upperstage

1

@Protron: Su respuesta es ¡increíble! ¡Gracias! Fui un poco más allá y creé mi propio método de extensión de clase.

/** 
* Instead of call Ext.extend method to create your new class extensions, you can use 
* My.extend. It is almost the same thing, but you pass a function as body for your new class, not 
* an object. Ex.: 
* 
* MyNewExtCompoment = My.extend(Ext.Compoment, function() { 
*  var myPrivateVar = 0; 
* 
*  //private 
*  function reset() { 
*  myPrivateVar = 0; 
*  } 
* 
*  //public 
*  function add(value) { 
*  try{ 
*   myPrivateVar = myPrivateVar + value; 
*  } catch(err){ 
*   reset(); 
*  } 
*  return myPrivateVar; 
*  } 
* 
*  return { 
*   add: add 
*  } 
* }, 'ux-my-new-component'); 
* 
* @param extendedClass my extended class 
* @param newClassBodyFunction my new class body 
* @param newClassXtype (optional) the xtype of this new class 
*/ 
My.extend = function(extendedClass, newClassBodyFunction, newClassXtype) { 
    var newClass = Ext.extend(extendedClass, newClassBodyFunction.call()); 
    if(newClassXtype) { 
     Ext.reg(newClassXtype, newClass); 
    } 
    return newClass; 
} 

De esta manera podemos ahorrar algo extra "()", y tenemos el "Ext.reg" llamada gratis. [] s

Cuestiones relacionadas