Pregunta

Tengo una gran xpage de 'Forma de pedido' que muestra 99 filas, con 3 cuadros de entrada de texto en cada fila. Para capturar cambios, he realizado una llamada a una función SSJS en el evento 'Onchange' de cada cuadro de entrada. La llamada simplemente envía la ID del producto, el tipo de cambio (qué columna) y la cantidad. La función SSJS luego conserva esos cambios en una variable SessionsCope (java.util.hashmap). No hay actualización asociada con el cambio.

Los cambios se procesan en masa cuando el usuario hace clic en el botón 'Enviar'. Esa es otra función SSJS que simplemente escribe todos los cambios en la base de datos Domino de back-end.

Todo eso parece funcionar bien y lo ha hecho durante un par de años. Sin embargo, parece que mis usuarios se están volviendo demasiado eficientes con la aplicación y están escribiendo más rápido de lo que puede mantener.

Mi código de depuración escribe cada cambio en la consola del servidor, y puedo ver dónde se ignoran algunos cambios simplemente si el usuario realiza cambios en una sucesión rápida (simplemente pestaña entre los cuadros de entrada). Es casi como si el servidor estuviera demasiado ocupado procesando el cambio anterior y salta uno para pasar a otro. A veces, se pierden bloques de cambios enteros, y luego la aplicación vuelve a retroceder cuando puede.

¿Estoy usando la técnica incorrecta para capturar los cambios? ¿Hay algo que pueda hacer para garantizar que la aplicación inicie el evento Onchange cada vez?

He probado esto usando IE8/9 y FF24. He visto otras publicaciones que proponen usar el evento 'OnKeyUp'. No creo que eso funcione en mi caso, ya que los usuarios pueden pedir cantidades de dos dígitos.

¡Cualquiera/todas las sugerencias serían agradecidas!

¿Fue útil?

Solución

Terry, debes volver a visitar la arquitectura. Si las actualizaciones se procesan al enviar, ¿por qué molestarse en enviarlas individualmente al servidor, como Tim señaló bien? Que haría yo:

  • Cree 2 clases de Java: un "ordenar" un "LineItem"
  • Deje que la clase de pedido implemente el mapa de la interfaz del mapa
  • Use la clase de pedido para su control de repetición (le dará la clave de cada LineItem como la variable de repetición)
  • Ate los campos dentro de la repetición al orden [repetido] .FieldName
  • Use el orden en una fuente de datos de objetos
  • Implemente el método Guardar en la clase de pedido y llámelo en el método Guardar de la fuente de datos de objetos

Muy de esquema, avísame si necesitas que elabore. El marco de colecciones Java es tu amigo.

Es más fácil de lo que parece:

   public class LineItem {

private String unid;
private String partno;
private int quantity;
private long unitprice;

/**
 * Constructor for new items
 */
public LineItem() {
    this.unid = null;
}

/**
 * Constructor for existing items
 */
public LineItem(Document doc) {
    this.unid = doc.getUniversalId();
    // more here
}


/**
 * @return the unid
 */
public String getUnid() {
    return this.unid;
}

/**
 * @return the partno
 */
public String getPartno() {
    return this.partno;
}
/**
 * @param partno the partno to set
 */
public void setPartno(String partno) {
    this.partno = partno;
}
/**
 * @return the quantity
 */
public int getQuantity() {
    return this.quantity;
}
/**
 * @param quantity the quantity to set
 */
public void setQuantity(int quantity) {
    this.quantity = quantity;
}
/**
 * @return the unitprice
 */
public long getUnitprice() {
    return this.unitprice;
}
/**
 * @param unitprice the unitprice to set
 */
public void setUnitprice(long unitprice) {
    this.unitprice = unitprice;
}

public void save(Database db) {
    Document doc = null;
    if (this.unid == null) {
        doc = db.createDocument();
        doc.replaceItem("Form", "LineItem");
    }
    doc.replaceItem("PartNo", this.partno);
    // More here
    doc.save();
}
}

y para el pedido, suponiendo que lo cargue de una recopilación de documentos.

public class Order implements Map<String, LineItem> {

// You might want to have a stack here to keep order
private final Map<String, LineItem> backingMap          = new LinkedHashMap<String, LineItem>();
private final Set<String>           deletedItemKeys     = new HashSet<String>();

// The key we use for new items when unid is null
private int                         lastNewItemNumber   = 0;

@Override
public int size() {
    return this.backingMap.size();
}

@Override
public boolean isEmpty() {
    return this.backingMap.isEmpty();
}

@Override
public boolean containsKey(Object key) {
    return this.backingMap.containsKey(key);
}

@Override
public boolean containsValue(Object value) {
    return this.backingMap.containsValue(value);
}

@Override
public LineItem get(Object key) {
    return this.backingMap.get(key);
}

@Override
public LineItem put(String key, LineItem value) {
    // Here it gets a little special
    // We need to prevent null keys
    if (key == null) {
        key = String.valueOf(this.lastNewItemNumber);
        lastNewItemNumber++;
    }
    this.deletedItemKeys.remove(key);
    return this.backingMap.put(key, value);
}

@Override
public LineItem remove(Object key) {
    this.deletedItemKeys.add(key.toString());
    return this.backingMap.remove(key);
}

@Override
public void putAll(Map<? extends String, ? extends LineItem> m) {
    for (Map.Entry<? extends String, ? extends LineItem> me : m.entrySet()) {
        this.put(me.getKey(), me.getValue());
    }
}

@Override
public void clear() {
    this.deletedItemKeys.addAll(this.backingMap.keySet());
    this.backingMap.clear();
}

@Override
public Set<String> keySet() {
    return this.backingMap.keySet();
}

@Override
public Collection<LineItem> values() {
    return this.backingMap.values();
}

@Override
public Set<java.util.Map.Entry<String, LineItem>> entrySet() {
    return this.backingMap.entrySet();
}

public void load(NotesDocumentCollection dc) throws NotesException {
    Document doc = dc.getFirstDocument();
    Document nextDoc;
    while (doc != null) {
        nextDoc = dc.getNextDocument(doc);
        LineItem li = new LineItem(doc);
        this.put(doc.getUniversalId(), li);
        doc.recycle();
        doc = nextDoc;
    }

    doc.recyle();
}

public void save(Database db) {
    for (LineItem item : this.backingMap.values()) {
        item.save(db);
    }

    // Now kill the left overs - needs error handling
    for (String morituri : this.deletedItemKeys) {
        Document delDoc = db.getDocumentByUnid(morituri);
        if (delDoc != null) {
            delDoc.remove(true);
        }
    }       
}
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top