كيف تجمع بين واجهة المستخدم المتعددة القائمة على Uibinder؟

StackOverflow https://stackoverflow.com/questions/2822273

سؤال

أحتاج إلى إدراج [عدد] من واجهة المستخدم المستندة إلى Uibinder إلى واحدة أخرى ، في مكان معين. يحتوي القطعة المدرجة على تصميم معقد إلى حد ما ، لذلك أحاول تحديده في HTML.

مرجع Panel.Add (...) فشل مع java.lang.illegalstateException: لا ينفذ هذا الوالد من واجهة المستخدم haswidgets. لا أعرف أي من الوالد الذي يسعده - innerpanel أو ReferencePanel.

إذا تمت إضافة كائن Referenceui إلى RootPanel ، ثم يتم إضافته إلى أسفل الصفحة. ولكن إذا تمت إضافته إلى Rootpanel أولاً ، فهناك رمز JavaScriptexception 3 (Hierarchy_request_err) عند إضافته إلى referepanel.

أي اقتراحات؟

public class AppUIDemo extends Composite {
    @UiTemplate("AppUIDemo.ui.xml")
    interface AppUIDemoUiBinder extends UiBinder<Widget, AppUIDemo> {
    }

    @UiTemplate("ReferenceUI.ui.xml")
    interface ReferenceUIUiBinder extends
            UiBinder<Widget, ReferenceUI> {
    }

    private static AppUIDemoUiBinder uiBinder = GWT
            .create(AppUIDemoUiBinder.class);
    private static ReferenceUIUiBinder refUIBinder = GWT
            .create(ReferenceUIUiBinder.class);

    @UiField
    FlowPanel referencePanel;

    public AppUIDemo() {
            initWidget(uiBinder.createAndBindUi(this));
            ReferenceUI reference = new ReferenceUI(refUIBinder);

            HTMLPanel innerPanel = reference.getRefPanel();
            innerPanel.getElement().setId(HTMLPanel.createUniqueId());
            referencePanel.add(innerPanel);
        }
}

 

public class ReferenceUI extends Composite {

    interface ReferenceUIUiBinder extends
            UiBinder<Widget,ReferenceUI> {
    }

    private static ReferenceUIUiBinder uiBinder = GWT
            .create(ReferenceUIUiBinder.class);


    @UiField
HTMLPanel refPanel;

    public ReferenceUI() {
        initWidget(uiBinder.createAndBindUi(this));
    }

    public CreditReferenceUI(final UiBinder<Widget, CreditReferenceUI> binder) {
        initWidget(binder.createAndBindUi(this));
    }

    public HTMLPanel getRefPanel() {
        return refPanel;
    }
}

Referenceui.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui"
    xmlns:gwittir="urn:import:com.totsp.gwittir.client.ui">
            <g:HTMLPanel ui:field="referencePanel">
            <table>
            <tr>
                <td>
                    <b>First Name</b></td>
                <td>
                    <b>Last Name</b></td>
                <td>
                    <b>Phone</b></td>
                <td>
                    <b>Fax</b></td>
            </tr>
            <tr>
                <td>
                    <gwittir:TextBox ui:field="referenceFirstName" styleName="input"/></td>
                <td>
                    <gwittir:TextBox ui:field="referenceLastName" styleName="input"/></td>
                <td>
                    <table><tr>
            <td> ( </td> <td>
                <gwittir:TextBox ui:field="referencePhoneAreaCode" styleName="input" maxLength="3"/></td>
                <td> ) </td> <td>
                <gwittir:TextBox ui:field="referencePhoneNumber" styleName="input" maxLength="7"/></td>
            <td> # </td> <td>
                <gwittir:TextBox ui:field="referencePhoneExtension" styleName="input" maxLength="25"/></td>
        </tr></table></td>
                <td>
                     <table><tr>
            <td> ( </td> <td>
                <gwittir:TextBox ui:field="referenceFaxAreaCode" styleName="input" maxLength="3"/></td>
                <td> ) </td> <td>
                <gwittir:TextBox ui:field="referenceFaxNumber" styleName="input" maxLength="7"/></td>
        </tr></table></td>
                </tr>
            <tr>
                <td style="text-align:right">
                    <b>Address: </b> Street</td>
                <td>
                    <gwittir:TextBox ui:field="referenceStreet" styleName="input"/></td>
                <td colspan="2" style="width:50%">
                    <table><tr><td>   City</td>
                    <td><gwittir:TextBox ui:field="referenceCity" styleName="input" maxLength="25"/></td>
                    <td> State </td>
                    <td class="state"><gwittir:TextBox ui:field="referenceState" styleName="input" maxLength="2"/></td>
                    <td> ZIP</td>
                    <td><gwittir:TextBox ui:field="referenceZIP" styleName="input" maxLength="9"/></td></tr></table>
                </td>
            </tr>
        </table>
    </g:HTMLPanel>
</ui:UiBinder>

appuidemo.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui"
    xmlns:gwittir="urn:import:com.totsp.gwittir.client.ui">
    <g:HTMLPanel ui:field="basePanel">
        <!--  <div id="MainContent">  -->
        <p><h2><b>Application Demo</b></h2></p>

        <g:FlowPanel ui:field="referencePanel">
        </g:FlowPanel>
    </g:HTMLPanel>
</ui:UiBinder>
هل كانت مفيدة؟

المحلول

سأبدأ بالإصلاح ، ثم انتقل لشرحه بعد ذلك.

إصلاح المشكلة

أسهل طريقة لإصلاح هذه المشكلة هي كما يلي. هذا هو الرمز الخاص بك:

HTMLPanel innerPanel = reference.getRefPanel();
innerPanel.getElement().setId(HTMLPanel.createUniqueId());
referencePanel.add(innerPanel);

استبدل ذلك بالرمز التالي. لاحظ أن السطر الأخير فقط قد تغير.

HTMLPanel innerPanel = reference.getRefPanel();
innerPanel.getElement().setId(HTMLPanel.createUniqueId());
referencePanel.add(reference);

بهذه الطريقة ، أنت تضيف Composite هدف. لن يكون هناك فرق للمستخدم ، مثل HTMLPanel (لك innerPanel) سيتم إرفاقها مباشرة في المستند.


بعض الخلفية

إضافة عنصر واجهة مستخدم إلى لوحة معقدة

عند إضافة عنصر واجهة مستخدم إلى لوحة معقدة (لوحة تحمل أكثر من عنصر واجهة مستخدم للأطفال) ، تحدث أربعة أشياء واحدة تلو الأخرى:

  1. يُطلب من القطعة أن تزيل نفسها من والدها الحالي
  2. تضيف اللوحة عنصر واجهة مستخدم إلى قائمة الأطفال
  3. تضيف اللوحة عنصر واجهة المستخدم إلى المستند
  4. يُطلب من القطعة أن تضع اللوحة كوالدها الجديد

إخبار عنصر واجهة مستخدم لإزالة نفسه من والدها

عندما يُطلب من الطفل أن يزيل نفسه من والده ، يحدث أحد ما يلي:

  • إذا لم يكن لدى المصنع الوالد ، فإنه لا يفعل شيئًا
  • إذا كانت القطعة هي طفل لوحة تنفذ HasWidgets, ، تطلب القطعة اللوحة لإزالة تلك القطعة
  • خلاف ذلك ، يلقي عنصر واجهة المستخدم IllegalStateException مع رسالة "لا ينفذ الوالد الخاص بالضغوط

عناصر واجهة المستخدم المركبة

عند الاتصال initWidget(Widget), ، يتم تعيين والد القطعة على Composite هدف.

المشكلة

عندما تحاول إضافة innerPanel, ، قيل لإزالة نفسها من والدها الحالي. innerPanel هو في الواقع جذر قالب uibinder الخاص بك. والدها Composite كائن (على وجه التحديد ، ReferenceUI). ينتج عن هذا الاستثناء الذي يتم إلقاؤه Composite لا ينفذ HasWidgets ولا يدعم إزالة عنصر واجهة المستخدم.

نصائح أخرى

لسوء الحظ ، لا يمكنك تعيين معرف لعنصر واجهة مستخدم في رمز Uibinder (أعتقد أنه لا يمكنك إلا للحصول على HTML العادي). لذلك تركت مع تعيين المعرف الصحيح عبر someWidget.getElement().setId() (كما فعلت في الكود أعلاه).

ما هو مفقود الآن ، على ما أعتقد ، هو عنصر نائب (Div ، تمتد ، أيا كان) مع المعرف الصحيح في HTMLPanel referencePanel, ، مثل ذلك:

<g:HTMLPanel ui:field="referencePanel">
    <div ui:field="referencePanelInner" />
</g:HTMLPanel>

و في AppUIDemo:

@UiField
DivElement referencePanelInner;
// ...
public AppUIDemo() {
    // ...
    referencePanelInner.setId(reference.getRefPanelId());
}

... ما لم تكن تريد إضافة المرجعية مباشرة إلى referencePanel - في هذه الحالة يجب عليك فقط استخدام أ FlowPanel :)

ملاحظة: IMHO ، يجب عليك إنشاء المعرف الفريد وتعيينه ReferenceUI.refPanel من ReferenceUI الفئة (وفضح المعرف) - وبهذه الطريقة لا تعبث مع "الداخلية" الخاصة بالعناصر واجهة المستخدم من بعض الأدوات الخارجية الخارجية.


حسنًا ، أعتقد أنني حصلت عليه. ال IllegalStateException يتم إلقاء الاستثناء لأنك تضيف ReferenceUI.refPanel (أو ReferenceUI.referencePanel, ، لا أعرف ما هو الاسم الحالي) ل AppUIDemo (ReferenceUI من الواضح أنه لا ينفذ HasWidgets) - عندما يجب أن تضيف الكل ReferenceUI reference مركب :) لا أعرف لماذا فعلت ذلك بهذه الطريقة في المقام الأول (ربما بسبب الفوضى بأكملها مع IDS) ، ولكن يجب أن يبدو الرمز مثل هذا:

public AppUIDemo() {
        initWidget(uiBinder.createAndBindUi(this));
        ReferenceUI reference = new ReferenceUI(refUIBinder);

        referencePanel.add(reference);
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top