我使用uibinder和UiRenderer创建了一个抽象单元格。我的数据源是列表的列表。让我们说汽车列表和每辆车都有一个型号列表。我将细胞添加到CellList。 每个单元格就像一张卡片,顶部有向前和向后按钮(我使用箭头图像和使用uihandler处理点击事件)和卡片显示模型的属性。点击的前后图像分别显示下一个和前一个模型。 单击图像时,我无法更改model_name(和其他div)。
<ui:with field="model_name" type="java.lang.String" />
<ui:with field="leftArrow" type="com.google.gwt.safehtml.shared.SafeHtml" />
<ui:with field="rightArrow" type="com.google.gwt.safehtml.shared.SafeHtml" />
<div>
<table width="100%" border="1" cellpadding="2" cellspacing="2"
bgcolor="#ffffff">
<tr valign="top">
<td>
<div ui:field="left" >
<ui:safehtml from='{leftArrow}' />
</div>
</td>
<td>
<div ui:field="model"><ui:text from="{model_name}" /></div>
</td>
<td>
<div ui:field="right" >
<ui:safehtml from='{rightArrow}' />
</div>
</td>
</tr>
</table>
</div>
我不确定如何访问模型div中的文本。随后还有更多的div,当点击图像时,其值/文本会发生变化。
public class NewCompCell extends AbstractCell<String> {
@UiField
String model_name;
@UiField
DivElement model;
static interface Images extends ClientBundle {
@Source("LeftArrow.png")
ImageResource LeftArrow();
@Source("rightArrow.png")
ImageResource rightArrow();
}
private Images images = GWT.create(Images.class);
private Renderer uiRenderer = GWT.create(Renderer.class);
public static interface Renderer extends UiRenderer {
void render(SafeHtmlBuilder sb, String value, String model_name,
SafeHtml leftArrow, SafeHtml rightArrow);
void onBrowserEvent(NewCompCell o, NativeEvent e, Element p, String n);
}
public NewCompCell() {
super(BrowserEvents.CLICK);
}
@Override
public void onBrowserEvent(Context context, Element parent, String value,
NativeEvent event,
ValueUpdater<String> valueUpdater) {
uiRenderer.onBrowserEvent(this, event, parent, value);
}
@Override
public void render(com.google.gwt.cell.client.Cell.Context context,
String value, SafeHtmlBuilder sb) {
uiRenderer
.render(sb, value, value,
AbstractImagePrototype.create(images.LeftArrow())
.getSafeHtml(),
AbstractImagePrototype.create(images.rightArrow())
.getSafeHtml());
}
@UiHandler({ "right" })
void onRightArrowClicked(ClickEvent event, Element parent, String string) {
model.setInnerText("next model");
}
@UiHandler({ "left" })
void onLeftArrowClicked(ClickEvent event, Element parent, String string) {
model.setInnerText("previous model");
}
}
当我点击图像时,我得到以下错误。
com.google.gwt.core.client.JavaScriptException:(TypeError)@ com.google.gwt.core.client.impl.Impl :: apply(Ljava / lang / Object; Ljava / lang / Object; Ljava / lang / Object;)([JavaScript object(36),JavaScript object(2),JavaScript object(204)]):无法设置null的属性'textContent' 在com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:249) 在com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136) 在com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:576) 在com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:284) 在com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91) 在com.google.gwt.core.client.impl.Impl.apply(Impl.java) 在com.google.gwt.core.client.impl.Impl.entry0(Impl.java:356) at sun.reflect.GeneratedMethodAccessor52.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) 在com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103) 在com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71) 在com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172) 在com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293) 在com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547) 在com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364) 在java.lang.Thread.run(未知来源)
答案 0 :(得分:0)
实现这些要求的一种更简单的方法是创建custom widget而不是自定义单元格。这个自定义小部件(例如“CarCard”)可能包含两个图标,任意数量的标签等。它还有为每个标签设置文本的方法,点击左右箭头的处理程序等。您可以使用UiBinder创建这个自定义小部件。
然后,当您加载汽车列表时,您可以执行以下操作:
for (Car car : cars) {
CarCard carCard = new CarCard();
carCard.setCar(car);
myContainerPanel.add(carCard);
}
自定义单元格在需要渲染数据并根据在单元格外部或整个单元格中发生的事件(例如,单击单元格本身)进行更新时更有用。当您希望在单元格内部具有类似小部件的行为时,这不是一个好的选择。
答案 1 :(得分:0)
UiBinder中定义的uiField可以通过在UiRenderer中为该字段定义一个getter来进行访问。 我收到错误是因为我试图直接访问uifield。
public static interface Renderer extends UiRenderer {
void render(SafeHtmlBuilder sb, String value, String model_name,
SafeHtml leftArrow, SafeHtml rightArrow);
DivElement getModel(Element parent); //make sure the uifield name matches the getter
void onBrowserEvent(NewCompCell o, NativeEvent e, Element p, String n);
}
此字段可以访问
@UiHandler({ "right" })
void onRightArrowClicked(ClickEvent event, Element parent, String string) {
uiRenderer.getModel(parent).setInnerText("next model");
}