2012-05-28 16 views
9

Amplié un Modelo existente agregando campos usando el prototipo. Todo funciona bien, los datos pueden recibirse desde el lado del servidor y pueden usarse en el lado del cliente. Pero cuando actualizo mis datos y los vuelva a enviar al servidor, el escritor del proxy no reconoce los campos "nuevos".Extender Ext.data.Model (agregar campos dinámicamente)

Para ser más específicos: Tengo un modelo como este:

Ext.define('Osgaar', { 
     extend: 'Ext.data.Model', 
     fields: [ 
     { name: 'first', type: 'string' }, 
     { name: 'second', type: 'string' }, 
     { name' 'third', type: 'string' } 
     ], 

     proxy: { 
     type: 'rest', 
     url: 'public/svcmethod', 
     reader: { 
      type: 'json', 
      root: 'data' 
     }, 
     writer: { 
      type: 'json', 
      writeAllFields: false 
     } 
     } 
    }); 

me estoy extendiendo el modelo de esa manera:

Osgaar.prototype.fields.add({ name: 'fourth', type: 'string' }); 

Me trataron de establecer writeAllFields a false para obtener todo atributos transferidos, solo hay aquellos del modelo definido, no el agregado con el prototipo (Fiddler lo confirma).

¿Alguien ahora es una forma de resolver esto sin definir un nuevo modelo?

Gracias de antemano.

Respuesta

11

Creo que la mejor solución es la siguiente:

Osgaar.prototype.fields.add(new Ext.data.Field({ name: 'fifth', type: 'string'})); // create Ext.data.Field constructor, not just simple Object 

Hice un rápido vistazo sobre la aplicación Writer, y aquí es un método que se llama por escritura() al escribir los datos:

getRecordData: function(record) { 
     var isPhantom = record.phantom === true, 
      writeAll = this.writeAllFields || isPhantom, 
      nameProperty = this.nameProperty, 
      fields = record.fields,   // <- look here 
      data = {}, 
      changes, 
      name, 
      field, 
      key; 

     if (writeAll) { 
      fields.each(function(field){ 
       if (field.persist) {   // <- checks the persist property! 
        name = field[nameProperty] || field.name; 
        data[name] = record.get(field.name); 
       } 
      }); 

Luego he comprobado el valor de persisten propiedad de un campo que se agrega al prototipo después de definir el modelo y resultó que es undefined. Esto se debe a que realmente no está creando una instancia de Ext.data.Field Ext.data.Field que heredaría todos los valores predeterminados de campo y otras cosas útiles, simplemente está agregando un Objeto simple a la colección de campos. Osgaar.prototype.fields es solo MixedCollection y como está trabajando directamente con él, no hay ningún lugar donde Ext.data.Field constructor pueda llamarse implícitamente.

Si es común que la lógica de su aplicación agregue campos de modelo sobre la marcha, considere implementar un método addField() en sus modelos personalizados (cree otra clase base en la cadena de herencia).

Espero que esto ayude, buena suerte! He estado usando ExtJS durante bastante tiempo, así que esto fue como una prueba para mí :)

+0

Esa es la solución. Agregar campos en la definición en sí parece establecer 'persist' en' true' (esto podría ser hecho por 'ModelManager', pero no lo he visto). Al agregar esto a través de prototipo, debe configurarse manualmente. ¡Muchas gracias! – LaOsgaar

+0

He actualizado mi respuesta, veo una solución un poco mejor y un poco más de investigación –

+0

Gracias por las explicaciones adicionales. Esto tiene sentido para mí. Lo probaré :) – LaOsgaar

1

Encontré otra solución para mi problema original.

En lugar de añadir los campos para el prototipo del modelo que hice lo siguiente:

Osgaar_Temp = Osgaar; 
delete Osgaar; 

Ext.define('Osgaar', { 
    extend: 'Osgaar_Temp', 
    fields: 
    [ 
     { name: 'typeCategories', type: 'string' } 
    ] 
}); 

Esta parece ser la mejor solución.

+0

Cada vez que hace esto, agrega otro nodo a la cadena de herencia que potencialmente conduce a una disminución del rendimiento en el mejor escenario. No llamaría confiable a esta solución, además de que hay muchas más líneas de código que la adición directa de un campo a la colección de campos. –

+0

Se acaba de llamar una vez, por lo que no puedo ver un problema aquí. Sí, puede haber más líneas de código, pero parece ser la solución más hermosa, ya que puede usar el comportamiento predeterminado sin hacer algo especial, IMO. – LaOsgaar

+0

No llamaría a esta solución * hermosa *, básicamente está pirateando el marco de herencia de clases para lograr los resultados deseados. Al final, obtienes una clase que hereda de sí misma ... –

Cuestiones relacionadas