how to change the text in an AbstractCell created using uibinder getting error Cannot set property 'textContent' of null

断了今生、忘了曾经 提交于 2019-12-11 07:50:06

问题


I created an abstract cell using uibinder and UiRenderer. My datasource is a list of a list. Lets say list of cars and each car has a list of models. I adding the cells to a CellList. Each cell is like like a card with forward and backward button on top(Im using arrow images and handling click event using uihandler) and the card display model's property. The forward and backward image on click show the next and the previous model respectively. Im not been able to change the model_name(and other divs) when images are clicked.

<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>

Im not sure how to access the text inside the model div. And subsequently there are more divs whose value/text changes when the images are clicked.

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");

}

}

When I click the images Im getting the below error.

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)]): Cannot set property 'textContent' of null at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:249) at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136) at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:576) at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:284) at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91) at com.google.gwt.core.client.impl.Impl.apply(Impl.java) at 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) at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103) at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71) at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172) at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293) at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547) at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364) at java.lang.Thread.run(Unknown Source)


回答1:


A much easier way to implement these requirements is to create a custom widget as opposed to a custom cell. This custom widget (e.g. "CarCard") may consist of two icons, any number of labels, etc. It will also have methods for setting the text for each label, click handlers for left and right arrows, etc. You can use a UiBinder to create this custom widget.

Then, as you load your list of cars, you can do something like:

for (Car car : cars) {
    CarCard carCard = new CarCard();
    carCard.setCar(car);
    myContainerPanel.add(carCard);
}

A custom cell is more useful in a situation where you need to render data and update it based on events that happen outside of a cell or with the entire cell (e.g. click on a cell itself). It is not a good option when you want to have a widget-like behavior inside a cell.




回答2:


The uiField defined in UiBinder can be access by defining a getter for that field in the UiRenderer. I was getting the error because I was trying it access the uifield directly.

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

}

This field can be access

    @UiHandler({ "right" })
void onRightArrowClicked(ClickEvent event, Element parent, String string) {

    uiRenderer.getModel(parent).setInnerText("next model");

}


来源:https://stackoverflow.com/questions/27003255/how-to-change-the-text-in-an-abstractcell-created-using-uibinder-getting-error-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!