Question

J'ai un grand `` formulaire de commande 'XPage qui affiche 99 lignes, avec 3 boîtes d'entrée de texte sur chaque ligne. Pour capturer des modifications, j'ai passé un appel à une fonction SSJ dans l'événement «Onchange» de chaque boîte d'entrée. L'appel envoie simplement l'ID du produit, le type de changement (quelle colonne) et la quantité. La fonction SSJS préserve ensuite ces changements dans une variable Sessionscope (java.util.hashmap). Il n'y a pas de rafraîchissement associé au changement.

Les modifications sont traitées en masse lorsque l'utilisateur clique sur le bouton «Soumettre». Il s'agit d'une autre fonction SSJ qui écrit simplement toutes les modifications de la base de données Domino back-end.

Tout cela semble fonctionner bien et que cela a fait pendant quelques années. Cependant, il semble que mes utilisateurs deviennent trop efficaces avec l'application et tapent plus rapidement qu'il ne peut le suivre.

Mon code de débogage écrit chaque modification de la console du serveur, et je peux voir où certaines modifications sont simplement ignorées si l'utilisateur apporte des modifications à succession rapide (ils tabortent simplement entre les cases d'entrée). C'est presque comme si le serveur était trop occupé à traiter la modification précédente et en sauter une pour passer à une autre. Parfois, des blocs entiers de modifications sont manqués, puis l'application reprend quand elle le peut.

Suis-je en utilisant la mauvaise technique pour capturer les changements? Y a-t-il quelque chose que je peux faire pour s'assurer que l'application initie l'événement Onchange à chaque fois?

J'ai testé cela en utilisant IE8 / 9 & FF24. J'ai examiné d'autres articles qui proposent à la place de l'événement «Onkeyup». Je ne pense pas que cela fonctionnerait dans mon cas, car les utilisateurs peuvent commander des quantités à deux chiffres.

Toutes les suggestions / toutes les suggestions seraient appréciées avec gratitude!

Était-ce utile?

La solution

Terry, you need to revisit the architecture. If the updates are processed on submit, why bother to send them individually to the server - as Tim nicely pointed out. What I would do:

  • create 2 Java classes: one "Order" one "LineItem"
  • Let the Order class implement the Map interface Map
  • Use the Order class for your repeat control (it will give you the key of each LineItem as the repeat variable)
  • Bind the fields inside the repeat to Order[RepeatKey].fieldName
  • Use Order in a object data source
  • Implement the save method in the Order class and call it in the save method of the object data source

Very rought outline, let me know if you need me to elaborate. The Java Collections Framework is your friend.

It is easier than it looks:

   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();
}
}

and for the Order - presuming you load from a document collection.

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);
        }
    }       
}
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top