0

私は次のUIの状況にあります:

<g:DisclosurePanel width="100%" ui:field="disclosurePanel">
       <g:customHeader>
         <g:HorizontalPanel width="100%" ui:field="tableRow">
           <g:cell width="16px" horizontalAlignment="ALIGN_CENTER">
             <g:Image url="images/plus-icon.gif" ui:field="icon"></g:Image>
           </g:cell>
           <g:cell width="20%">
             <g:Label ui:field="productName"></g:Label>
           </g:cell>
           <g:cell>
             <g:Anchor ui:field="info"><ui:msg>More info...</ui:msg></g:Anchor>
           </g:cell>
         </g:HorizontalPanel>
       </g:customHeader>
       <g:VerticalPanel width="100%" ui:field="details">
         <!-- details panel here -->
       </g:VerticalPanel>
     </g:DisclosurePanel>

そして、イベントハンドラーメソッドをにバインドしたいと思いAnchor infoます。ただし、ヘッダーにあるすべてのウィジェットは、次の方法で何かをフックした場合でも、開示パネルを開いたり閉じたりしますinfo

@UiHandler("info")
public void onInfoClicked(ClickEvent event)
{
   // do something custom, but do not open/close the disclosurepanel
}

カスタムコンポジットなどを作成せずにこれを実現できることを願っています。手伝って頂けますか?

4

2 に答える 2

1

設計どおりに機能します。内部に配置する各要素には、要素をDisclosurePanel開閉するクリックハンドラーがあります。したがって、ヘッダー内には、画像やテキストのみが含まれている必要があります。基本的には、技術的なロジックを持たないonyl要素です。リンクがヘッダー内にないように、html要素を別の方法で配置することを検討します...

本当に本当にヘッダー内に配置する必要がある場合は、これをアンカークリックイベントに追加できます。

disclosurePanel.setOpen(!disclosurePanel.isOpen());

これにより、DisclosurePanelの以前の状態が復元されます。良い部分は、それが非常に速いので、DisclosurePanelの開閉さえ見えないということです。悪い部分は、これが本当に悪いデザインであるということです。

追加:DisclosurePanelはアンカーを使用して表示されます。アンカーは定義ごとにブロック要素のみを許可するため、このように使用しないでください。(アンカー内にdivを配置することは正しいですか?を参照してください。 )

于 2012-04-12T09:14:02.867 に答える
1

DisclosurePanelのヘッダーはプライベート内部クラスClickableHeaderです。

private final class ClickableHeader extends SimplePanel {

private ClickableHeader() {
  // Anchor is used to allow keyboard access.
  super(DOM.createAnchor());
  Element elem = getElement();
  DOM.setElementProperty(elem, "href", "javascript:void(0);");
  // Avoids layout problems from having blocks in inlines.
  DOM.setStyleAttribute(elem, "display", "block");
  sinkEvents(Event.ONCLICK);
  setStyleName(STYLENAME_HEADER);
}

@Override
public void onBrowserEvent(Event event) {
  // no need to call super.
  switch (DOM.eventGetType(event)) {
    case Event.ONCLICK:
      // Prevent link default action.
      DOM.eventPreventDefault(event);
      setOpen(!isOpen);
  }
}
}

あなたのコードを仮定します:

@UiField
DisclosurePanel p;

//call this somewhere once on widget creation to 
//prevent header's default click handler
private void myInit()
{
    p.getHeader().unsinkEvents(Event.ONCLICK);
}

@UiHandler("info")
public void onInfoClicked(ClickEvent event)
{
   //trigger "standard" click handler if you want
   if(someCondition) {
       //convert GwtEvent descendant to NativeEvent descendant;
       p.getHeader().onBrowserEvent(event.getNativeEvent().<Event> cast());
   }

   // do something custom, but do not open/close the disclosurepanel
}
于 2012-04-12T09:29:15.213 に答える