Можно ли через xPages API получить доступ к панели, которая находится внутри повторяющегося элемента управления?

Это относится к моему вопросу, который я разместил ранее Необходимо узнать, как пометить поле в коллекции документов, которая находится в элементе управления повторением

Я пытаюсь получить доступ к панели, которая находится в элементе управления повторением, используя API xPages, но мне это не удалось, потому что, когда я пытаюсь получить дескриптор элемента управления повтором и пытаюсь пройти через его дочерние элементы, я получаю только строку таблицы и ячейки, которые помещаются в панель, но я не получаю панель как дочерний элемент повтора. Вот код, который я использую для этого. Пожалуйста, предложите, есть ли другой способ получить доступ к панели в повторе. Мне нужно так, чтобы получить доступ к источникам данных на панели, чтобы сохранить их по отдельности.

function getComponentValueInRepeat(strRepeatID, strCompID, tmpRowIndex) {
var repeatComp:com.ibm.xsp.component.UIRepeat = getComponent(strRepeatID);
var rowIndex = 1;
if (null != repeatComp) {
    var repeatList:java.util.Iterator = repeatComp.getFacetsAndChildren();
    var repeatContainer:com.ibm.xsp.component.UIRepeatContainer = null;
    var entityComponent:javax.faces.component.UIComponent = null;

    while (repeatList.hasNext()){
        repeatContainer = repeatList.next();
        var componentList = repeatContainer.getChildren();

        while (componentList.length == 1 && 
                (componentList[0].getClass().getName().equals("com.ibm.xsp.component.xp.XspTable") |
                componentList[0].getClass().getName().equals("com.ibm.xsp.component.xp.XspTableRow"))) {
            componentList = componentList[0].getChildren();
        }

        for (compArrLoopCont = 0 ; compArrLoopCont < componentList.length; compArrLoopCont++) {
            entityComponent = componentList[compArrLoopCont];

            if (entityComponent.getChildCount() == 1 && 
                    entityComponent.getClass().getName().equals("com.ibm.xsp.component.xp.XspTableCell")) {
                entityComponent = entityComponent.getChildren();
                entityComponent = entityComponent[0];
            }

            if (entityComponent.getId().equals(strCompID) && tmpRowIndex == rowIndex) {
                if (null == entityComponent.getValue()) {
                    return "";
                } else {
                    return entityComponent.getValue();
                }

            }
        }
        //print ("hello +++ " + entityComponent[0].getId());
        rowIndex++;
    }
} else {
    print ("exception...");
}

person Nash    schedule 17.12.2013    source источник
comment
Редактирование вашего вопроса с исходным кодом XPage xp:repeat и xp:panel внутри него поможет лучше понять вашу проблему.   -  person Naveen    schedule 17.12.2013
comment
Привет, Навин, код для повтора и панели был указан в моем предыдущем вопросе, на который я разместил ссылку в этом вопросе (нужно знать, как поставить печать в поле в коллекции документов, которая находится в элементе управления повтором)   -  person Nash    schedule 17.12.2013
comment
Скорее всего, вы пытаетесь сделать что-то, что имеет лучшее решение, чем то, о чем вы просите. Сделайте шаг назад от «как я хочу это решить» и объясните: какова цель. Если решение нелегко понять, ваш подход требует пересмотра.   -  person stwissel    schedule 17.12.2013
comment
Часто задают вопрос о достижении повторения. Дети повтора существуют только один раз. Задача повтора состоит в многократной обработке одного и того же набора дочерних элементов. Таким образом, вы не можете получить, например, третью панель в вашем повторе, потому что есть только одна панель, которая обрабатывается снова и снова. Лучший подход — создать слой модели данных и привязать к нему свой повтор; сошлитесь на этот ответ в качестве примера: /17948552/ Тогда вы сможете напрямую обращаться к данным без поиска компонентов.   -  person Tim Tripcony    schedule 17.12.2013


Ответы (1)


При работе с данными вы всегда должны стремиться к данным, а не к пользовательскому интерфейсу. Вы меняете свой интерфейс, ваша логика ломается. Есть несколько вариантов вашей задачи:

  • Поместите индивидуальную кнопку сохранения внутри вашей панели. Тогда document1.save() прекрасно справится с задачей.
  • Храните идентификаторы ваших документов в переменной viewScope, и когда какое-то действие требует сохранения документа, используйте это значение для определения документа (возможно, беспорядочно).
  • Не привязывайтесь к документам, привяжите свои значения к набору пользовательских объектов. Эти объекты заполняются вашей логикой управления повторением и сохраняются в viewScope. Когда вы нажимаете кнопку «Сохранить», все измененные значения отправляются, и в ваших сеттерах вы можете определить флаг «Мне нужно сохранить это» и сохранить его.

Класс может выглядеть примерно так:

  public class Approval() {
      private boolean isDirty = false;
      private final String unid;
      private String approver;
      // more fields here;

      public Approval(String unid, String approver /* more values or pass the NotesViewEntry */) {
          this.unid = unid;
          this.approver = approver;
      }

      public String getUnid() {
          return this.unid;
      }

      public String getApprover() {
          return this.Approver;
      }

      public void setApprover(String newApprover) {
             if (!this.approver.equals(newApprover)) {
                this.isDirty = true;
             }
             this.approver = newApprover;
      }

      public void save(Database db) {
           if (!this.isDirty) {
              return; // No action needed
           }
           Document doc = db.getDocumentByUnid(this.unid);
           doc.replaceItemValue("Approver",this.approver);
           doc.save();
      }
  }

Таким образом, ваш повторный код будет выглядеть примерно так:

// If we looked them up before we don't need to do anything
if (viewScope.approvals) {
    return viewScope.approvals;
}
// Look up the employee details view to get the employee appraisal details from the current database
var curDB:NotesDatabase = session.getCurrentDatabase();
var vwlkApprView:NotesView = curDB.getView("vwlkAllApprApper");
var collDocAppr:NotesViewEntryCollection = vwlkApprView.getAllEntriesByKey(sessionScope.EmployeeID);
// Don't do a count, slow!
var result = new java.util.Vector();
// Add all approvals
var ve:NotesViewEntry = collDocAppr.getFirstEntry();
while (ve != null) {
   var nextVe = ve.getNextEntry(ve);
   // make this next line nicer!
   result.add(new demo.Approval(ve.getUniversalid(),ve.getColumnValues().get(0))); // eventually check to avoid categories?
   ve.recyle();
   ve = nextVe;
}
viewScope.approvals = result.isEmpty() ? null : result;
collDocAppr.recyle();
vwlkApprView.recycle();
return viewScope.approvals;

Затем ваша кнопка сохранения будет перебирать коллекцию.

 for (var a in viewScope.approvals) {
    a.save(database);
 }

Конечно, другой подход заключается в том, чтобы использовать ОДИН bean-компонент в качестве источника данных объекта для страницы, которая имеет функцию getApprovals(database) для ее инициализации.

person stwissel    schedule 17.12.2013