Vistas

Nuevo metodo addFragment

De MorfeoWiki

Browser con capacidad AJAX

  • Mostrada una presentación, queda cacheado el objeto DocumentTag. Podemos añadirle un método como el siguiente para que nos devuelva un Tag dado un identificador.
  public Tag getTag (String id){};
  • Teniendo este tag, sería invocar la renderización del mismo, es decir, a su writer_technology(WriterData wd). Para ello habría que añadir la lógica necesaria para soportar ésto y sería tan fácil como cada vez que se crea un Tag añadir la referencia del mismo a un Map del DocumentTag.
  public void addTag (String id, Tag tag);
  • Así si se ejecuta desde la vista lo siguiente:
  mymw.ui.addfragment("id", "where");
  • El algoritmo a ejecutar sería:
  DocumentTag documentTag = DocumentCache.getInstance().get(context);
  Tag tag = documentTag.getTag (id);
  if (tag != null){
     if (CmtConstants.HTML.equals("technology")) {
        tag.write_html_web_3_2(new WriterData( out, request, "technology" ));
     } else if (CmtConstants.XHTML_MP.equals("technology")) {
        tag.write_xhtml_mp(new WriterData( out, request, "technology" ));
     }
  } else {
     // JSON encapsulando error.
  }
  • Al crear el WriterData le pasamos un Outputter, lo leemos y creamos el objeto json correspondiente y ejecutamos sendObject(json). En la presentación meterlo en el innerHTML correspondiente para id = "where".
  • Habrá que modificar la clase Outputter para tener un constructor que permita pasarle un java.io.Writer como salida y no un JspWriter como hasta ahora. Y así le damos como argumento una clase que extienda de Writer y lo que haga sea crear el objeto json por debajo y así ya lo tenemos disponible para mandar. El objeto JSON sería un valor, es decir, el fragmento que vamos a encapsular en un innerHTML.
  JSONWriter extends java.io.Writer {
     // Crear un JSON con el fragmento a añadir.
  }
  • El mayor problema antes de implementar todo ésto es hacer un refactorización del WebServerArchitecture. En necesaria porque la renderización se ha de invocar desde el WebServerArchitecture y según lo tenemos ahora es el PresEngine el que qué vé el servidor (transcoder, cms, content manager, url manager, etc).
  • Otra cosa a tener en cuenta será en momento de generación obtener los addfragment que haya en la presentación. Mirar el atributo que indica el identificador donde queremos añadir el fragmento y cuando nos llegue un tag y él sepa mediante un flag si es susceptible de añadir contenido o no, crear un div con ese id que encapsule dicho tag. Por ejemplo cuando tengamos algo de este estilo:
  <mymw:head>
     <ev:listener event="click" target="lnk1" handler="javascript:mymw.ui.addFragment('p1', 'p2')"/>
  </mymw:head>
  ....................
  <mymw:div id="p1">
     <mymw:link id="lnk1">Añadir</mymw:link>
  </mymw:div>
  <mymw:div id="p2" expr="false">
     <mymw:label id="lab1">Has pulsado</mymw:label>   
  </mymw:div>
  • Se anidará el tag 'p2' en:
  <div id="_addFragment_p2">...</div> ó <span id="_addFragment_p1">...</span>
  • De esta forma al ejecutar mymw.ui.addFragment('p1', 'p2'), el fragmento se añadirá a través del innerHTML del anterior span o div a la hora de renderizar la presentación.
  • ¿Cómo renderizarlo? ¿Añadir el fragmento al final o al comienzo del control destino?.

Browser sin capacidad AJAX

  • Habrá que saber cuando se ha ejecutado un addFragment() desde el browser. Sin AJAX esto será una recarga de la página, sólo que incluyendo el fragmento que antes no se presentaba y ahora ha sido solicitada su inclusión.
  • Cuando no se soporta AJAX, el evento será addFragment y dos nuevos parámetros, uno que indicará que fragmento se ha de incluir y otro el dónde.
  • Cuando llegue ese evento, se recargará la página y el párrafo donde se ha de incluir el fragmento deberá preguntar al document tag por el fragmento en cuestión e invocar a su Writer. NO hará falta navegar por todo el árbol hasta llegar al DocumentTag se puede hacer preguntando al DocumentCache ya que se dispone de la instancia WriterData.
  • Aquí me surge una pregunta, si yo tengo un enlace cuyo click es addFragment bla bla.. si se pulsa dos veces eso implica que se añade dos veces el fragmento? Si es así, con AJAX el tema por definición queda resuelto. Pero sin AJAX, habría que añadir una variable de contexto que se autoincremente cada vez que se aplique un addFragment. Se pulso una vez vale 2 la variable, así cuando se pulse por segunda vez esa inclusión se deberá renderizar dos veces.
  • Los problemas inherentes de la inclusión 2 o más veces son:
  1. La duplicación de identificadores. Esto implica XML mal formado. Atributos id deben tener valores distintos para una misma autoría XML. Ejemplo incluir <mymw:img id="l1" alt="elQueSea"> renderizará dos imagenes con el mismo atributo id.
  2. La duplicación de variables de binding. Por ejemplo, incluir dos o más veces un <mymw:entryfield..> con atributo bind definido.
  • Pienso que el primero se debería resolver (duplicación de ids) pero el segundo dependerá del desarrollador, debería darse cuenta de estas cosas supongo.

Temas abiertos

  • ¿El añadir un fragmento se hace antes o después de renderizar el control que lo contendrá?
  • ¿La inclusión sólo será permitida en <mymw:div> tag?
  • ¿Se permitirá varias inclusiones de fragmentos?
  • ¿La inclusión es de algo definido en otra presentación o en la misma vista?
    • Parece lógico que sea algo definido en otra vista, a no ser que se añada algo de la misma que tenga el atributo display evaluado como falso.