2013-10-15 20 views
3

我有一个包含表格的检票面板。这是它的构造:在门票中刷新包含面板的表格

public NotFinishedExamsPanel(String id, final String userId, String[] egal) { 
    super(id, new ResourceModel("notFinishedExams"), true); 

    this.setOutputMarkupId(true); 

    MySystem mysystem = ((MySession) Session.get()).getMySystem(); 
    String uid = ((MySession) Session.get()).getUsername(); 

    ArrayList<ExamData> exams = new ArrayList<ExamData>(); 
    try { 
     if (!mysystem.account(userId).isStudent()) { 
      return; 
     } 

     for (String exId : mysystem.exams()) { 
      Exam ex = mysystem.exam(exId); 
      if ((!(ex.hasResult(mysystem.account(userId).student().id()) && (ex.isPublished())))) { 
       exams.add(new ExamData(mysystem.account(userId).student().id(), exId)); 
      } 
     } 

     ExamProvider exProv = new ExamProvider(exams); 
     ArrayList<IColumn<ExamData, String>> columns = new ArrayList<IColumn<ExamData, String>>(); 
     columns.add(new PropertyColumn<ExamData, String>(new ResourceModel("title", "Titel"), "title")); 
     columns.add(new PropertyColumn<ExamData, String>(new ResourceModel("date", "Datum"), "date")); 
     columns.add(new PropertyColumn<ExamData, String>(new ResourceModel("time", "Uhrzeit"), "time")); 
     columns.add(new PropertyColumn<ExamData, String>(new ResourceModel("location", "Ort"), "location")); 
     columns.add(new PropertyColumn<ExamData, String>(new ResourceModel("status", "Status"), "status") { 
      private static final long serialVersionUID = 7758862055950720446L; 
      public void populateItem(Item item, String componentId, IModel rowModel) { 
       Status status = ((ExamData) rowModel.getObject()).status; 
       item.add(new ShowExamStatusPanel(componentId, status)); 
      } 
     }); 
     columns.add(new PropertyColumn<ExamData, String>(new Model<String>(""), "status") { 
      private static final long serialVersionUID = 7758862055950720446L; 
      public void populateItem(Item item, String componentId, IModel rowModel) { 
       String examId = ((ExamData) rowModel.getObject()).examId; 
       String studentId = ((ExamData) rowModel.getObject()).studentId; 
       Status status = ((ExamData) rowModel.getObject()).status; 
       item.add(new ChangeExamStatusPanel(componentId, userId, examId, studentId, status)); 
      } 
     }); 

     DefaultDataTable<ExamData, String> ddt = new DefaultDataTable<ExamData, String>("datatable", columns, exProv, 64); 
     collapsible.add(ddt); 
    } catch (NoSuchElementException e) { 
     error(e.getMessage()); 
    } 
} 

可折叠的是WebMarkupContainer(div标签)从超类继承(超类扩展面板)。 正如你所看到的,在最后两列中,我不只是放在一个简单的文字,而是一个特殊的面板。

ShowExamStatusPanel包含显示无论您是这门考试或没有登录标签:

class ShowExamStatusPanel extends Panel { 
    private static final long serialVersionUID = 6359496765268390462L; 

    public ShowExamStatusPanel(String id, final Status status) { 
     super(id); 
     this.setOutputMarkupId(true); 
     Label showStatus = new Label("showStatus", new AbstractReadOnlyModel<String>() { 
      private static final long serialVersionUID = 1L; 

      public String getObject() { 
       return ((status == Status.SIGNED_IN || status == Status.SIGNED_IN_CLOSED) ? (new ResourceModel("signed_in").getObject()) : (new ResourceModel("not_signed_in")).getObject()); 
      } 
     }); 
     showStatus.add(new AttributeModifier("class", ((status == Status.SIGNED_IN || status == Status.SIGNED_IN_CLOSED) ? "examSignedUpColor" : "examNotSignedUpColor"))); 
     this.add(showStatus); 
    } 
} 

ChangeExamStatusPanel包含切换你的状态参加考试的链接(它在签署,如果你不和迹象关闭否则):

class ChangeExamStatusPanel extends Panel { 
    private static final long serialVersionUID = -8527825882073976118L; 

    public ChangeExamStatusPanel(final String id, final String userId, final String examId, final String studentId, final Status status) { 
     super(id); 
     this.setOutputMarkupId(true); 
     MySystem mysystem = ((MySession) Session.get()).getMySystem(); 
     AjaxLink cesl= new AjaxLink("changeExamStatusLink") { 
      private static final long serialVersionUID = 4306084754982648221L; 

      @Override 
      public void onClick(AjaxRequestTarget target) { 
       MySystem mysystem = ((MySession) Session.get()).getMySystem(); 
       try { 
        if (status == Status.SIGNED_IN) { 
         mysystem.exam(examId).removeParticipant(userId, studentId); 
        } else if (status == Status.NOT_SIGNED_IN) { 
         mysystem.exam(examId).addParticipant(userId, studentId); 
        } 
       } catch (Exception e) { 
        NotFinishedExamsPanel.this.error(e.getMessage()); 
       } 
       target.addChildren(NotFinishedExamsPanel.this, ChangeExamStatusPanel.class); 
       target.addChildren(NotFinishedExamsPanel.this, ShowExamStatusPanel.class); 
       target.add(NotFinishedExamsPanel.this); 
      } 
     }; 
     Label ceslText = new Label("linkText", ("[" + (new ResourceModel((status == Status.SIGNED_IN || status == Status.SIGNED_IN_CLOSED) ? "sign_off" : "sign_in")).getObject() + "]")); 
     cesl.add(ceslText); 
     ceslText.setVisibilityAllowed(status == Status.SIGNED_IN || status == Status.NOT_SIGNED_IN); 
     this.add(cesl);   
    } 
} 

当链接被点击,我要被刷新的表,因为登录的状态为一个考试已经改变。但我没有得到这个工作。使用上面的代码,当我点击链接时没有任何反应。如果我然后按F5并刷新整个页面,我会看到更改。

如何刷新表格(包括内部面板),我该怎么做?

这里的HTML文件,如果需要的话:

NotFinishedExamsPanel.html:

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"> 
<head> 
</head> 
<body> 
    <wicket:extend> 
     <table wicket:id="datatable" class="datatable" style="margin:0px"></table> 
    </wicket:extend> 
</body> 
</html> 

NotFinishedExamsPanel $ ShowExamStatusPanel.html:

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"> 
<wicket:panel> 
    <span wicket:id="showStatus"></span> 
</wicket:panel> 
</html> 

NotFinishedExamsPanel $ ChangeExamStatusPanel.html:

<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"> 
<wicket:panel> 
    <a wicket:id="changeExamStatusLink" href="#"><span wicket:id="linkText"></span></a> 
</wicket:panel> 
</html> 

ExamProvider.java:

class ExamProvider extends SortableDataProvider<ExamData, String> { 
    private static final long serialVersionUID = 1476722834865141105L; 
    private ExamDataProviderComparator comparator = new ExamDataProviderComparator(); 
    private List<ExamData> examList; 

    public ExamProvider(List<ExamData> examList) { 
     this.examList = examList; 
     this.setSort("date", SortOrder.DESCENDING); 
    } 

    public Iterator<ExamData> iterator(long first, long count) { 
     List<ExamData> newList = new ArrayList<ExamData>(this.examList); 
     Collections.sort(newList, comparator); 
     return newList.subList((int) first, (int) (first + count)).iterator(); 
    } 

    public long size() { 
     return this.examList.size(); 
    } 

    public IModel<ExamData> model(final ExamData object) { 
     return new AbstractReadOnlyModel<ExamData>() { 
      private static final long serialVersionUID = -3048436145666499501L; 

      public ExamData getObject() { 
       return (ExamData) object; 
      } 
     }; 
    } 

    class ExamDataProviderComparator implements Comparator<ExamData>, Serializable { 
     private static final long serialVersionUID = 7660088204512731476L; 

     public int compare(final ExamData o1, final ExamData o2) { 
      PropertyModel<Comparable> model1 = new PropertyModel<Comparable>(o1, getSort().getProperty()); 
      PropertyModel<Comparable> model2 = new PropertyModel<Comparable>(o2, getSort().getProperty()); 

      int result = 0; 
      if (model1.getObject() instanceof String && model2.getObject() instanceof String) { 
       if (getSort().getProperty().equalsIgnoreCase("date")) { 
        try { 
         SimpleDateFormat sdt = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN); 
         Date d1 = sdt.parse(model1.getObject().toString()); 
         Date d2 = sdt.parse(model2.getObject().toString()); 
         result = d1.compareTo(d2); 
        } catch (ParseException e) { 
         result = Collator.getInstance(Locale.GERMAN).compare(model1.getObject(), model2.getObject()); 
        } 
       } else { 
        result = Collator.getInstance(Locale.GERMAN).compare(model1.getObject(), model2.getObject()); 
       } 
      } else { 
       result = model1.getObject().compareTo(model2.getObject()); 
      } 
      if (!getSort().isAscending()) { 
       result = -result; 
      } 

      return result; 
     } 

    } 

} 
+0

你能否解释一下如何在'ChangeExamStatusPanel'中获得对'NotFinishedExamsPanel.this'的引用? – mrak

+0

还有一个问题:什么是“ExamProvider”? LoadableDetachableModel? – mrak

+0

@mrak类“ChangeExamStatusPanel”和“ShowExamStatusPanel”位于“NotFinishedExamsPanel”内部,它们是内部类。所以我可以访问它们中的NotFinishedExamsPanel。 ExamProvider扩展了SortableDataProvider 。我将把它的代码放在我的帖子中。 – DonGiovanni

回答

1

检票调用构造(页或组件)仅当页面构造。 因此,在将NotFinishedExamsPanel添加到AjaxRequestTarget后,Wicket 正在根据ArrayList<ExamData> exams(仍然相同)中的数据刷新表格。

我建议你下面的方法来impelemnt的ExamProvider (我是不是能够测试代码,以便采取只作为建议):


    static class ExamProvider extends SortableDataProvider<ExamData, String> { 

     private static final long serialVersionUID = 1L; 

     private static final String DEFAULT_SORT = "foobar"; 

     private IModel<List<ExamData>> examsModel = new ExamDataLoader(); 

     @Override 
     public Iterator<ExamData> iterator(long first, long count) { 
      SortParam<String> sort = getSort(); 

      List<ExamData> examDataList = examsModel.getObject(); 

      // TODO sort 
      String orderByColumn = sort != null ? DEFAULT_SORT : sort.getProperty(); 
      boolean desc = sort != null ? true : !sort.isAscending(); 

      return examDataList.iterator(); 
     } 

     @Override 
     public long size() { 
      return examsModel.getObject().size(); 
     }; 

     @Override 
     public IModel<ExamData> model(ExamData data) { 
      final String examId = data.getExamId(); 
      return new LoadableDetachableModel<ExamData>() { 
       @Override 
       protected ExamData load() { 
        MySystem mysystem = MySession.get().getMySystem(); 
        final long userId = mysystem.account(userId).student().id(); 
        Exam ex = mysystem.exam(examId); 
        return new ExamData(mysystem.account(userId).student().id(), examId); 
       } 
      }; 
     } 

     @Override 
     public void detach() { 
      examsModel.detach(); 
      super.detach(); 
     } 
    } 

有了:


    static class ExamDataLoader extends LoadableDetachableModel<List<ExamData>> { 

     private static final long serialVersionUID = 1L; 

     @Override 
     protected List<ExamData> load() { 
      MySystem mysystem = MySession.get().getMySystem(); 
      long userId = mysystem.account(userId).student().id(); 

      List<String> examsIds = mysystem.exams(); 
      List<ExamData> exams = new ArrayList<>(examsIds.size()); 
       for (String exId : mysystem.exams()) { 
        Exam ex = mysystem.exam(exId); 
        if ((!(ex.hasResult(userId) && (ex.isPublished())))) { 
         exams.add(new ExamData(mysystem.account(userId).student().id(), exId)); 
        } 
       } 
       return exams; 
      } 
     } 

为了让您的生活更轻松一些,请将get()的静态方法隐藏在MySession中:


    public static MySession get() { 
     return (MySession) Session.get(); 
    } 

最后一件事:永远不要改变构造函数中的可见性(或组件的其他属性)(与初始问题相同的参数)。 因此,而不是:

if (!mysystem.account(userId).isStudent()) { return; }

覆盖onConfigure方法 广告设置根据给定的限制知名度。