سؤال

لديّ XPAGE "نموذج ترتيب كبير" يعرض 99 صفًا ، مع 3 مربعات إدخال نصية في كل صف. لالتقاط التغييرات ، قمت بإجراء مكالمة إلى وظيفة SSJS في حدث "Onchange" لكل مربع إدخال. ترسل المكالمة ببساطة معرف المنتج ، ونوع التغيير (أي العمود) والكمية. ثم تحافظ وظيفة SSJS على هذه التغييرات في متغير SessionsCope (java.util.hashmap). لا يوجد تحديث مرتبط بالتغيير.

تتم معالجة التغييرات بشكل جماعي عندما ينقر المستخدم على زر "إرسال". هذه وظيفة أخرى SSJS تكتب ببساطة جميع التغييرات في قاعدة بيانات الدومينو الخلفية.

يبدو أن كل شيء يعمل بشكل جيد وقد فعل ذلك لبضع سنوات. ومع ذلك ، يبدو أن المستخدمين أصبحوا فعالين للغاية مع التطبيق ، ويكتبون بشكل أسرع مما يمكنه مواكبة ذلك.

يكتب رمز التصحيح الخاص بي كل تغيير إلى وحدة تحكم الخادم ، ويمكنني أن أرى أين يتم تجاهل بعض التغييرات ببساطة إذا قام المستخدم بإجراء تغييرات في الخلافة السريعة (فهي ببساطة تبويب بين مربعات الإدخال). يبدو الأمر كما لو أن الخادم مشغول جدًا بمعالجة التغيير السابق ويتخطى المرء للانتقال إلى آخر. في بعض الأحيان ، يتم تفويت كتل كاملة من التغييرات ، ثم يتم تقديم التطبيق احتياطيًا عندما يمكن ذلك.

هل أستخدم التقنية الخاطئة لالتقاط التغييرات؟ هل هناك شيء يمكنني القيام به لضمان بدء التطبيق في حدث OnChange في كل مرة؟

لقد اختبرت هذا باستخدام IE8/9 و FF24. لقد نظرت إلى المنشورات الأخرى التي تقترح استخدام حدث "onkeyup" بدلاً من ذلك. لا أعتقد أن ذلك سيعمل في حالتي ، حيث قد يطلب المستخدمون كميات من رقمين.

أي/كل الاقتراحات سيكون موضع تقدير بامتنان!

هل كانت مفيدة؟

المحلول

تيري ، تحتاج إلى إعادة النظر في الهندسة المعمارية. إذا تمت معالجة التحديثات عند إرسالها ، فلماذا تهتم بإرسالها بشكل فردي إلى الخادم - كما أشار تيم بشكل جيد. ماذا كنت سأفعل:

  • إنشاء فئتين java: One "Order" One "LineItem"
  • دع فئة الطلب تنفذ خريطة واجهة الخريطة
  • استخدم فئة الطلب لعنصر التحكم في التكرار (سيعطيك مفتاح كل LineItem كمتغير تكرار)
  • ربط الحقول داخل التكرار لطلب [REPERKEY] .FieldName
  • استخدم الطلب في مصدر بيانات الكائن
  • قم بتنفيذ طريقة حفظ في فئة الطلب واتصل بها بطريقة حفظ مصدر بيانات الكائن

مخطط تفصيلي للغاية ، اسمحوا لي أن أعرف إذا كنت بحاجة لي أن أوضح. إطار مجموعات Java هو صديقك.

انها اسهل مما تبدو عليه:

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

وبالنسبة للطلب - على افتراض تحميلك من مجموعة مستندات.

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);
        }
    }       
}
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top