0

MarkupWriter を介してプログラムで html を追加するチュートリアルをたくさん見てきましたが、コンポーネントが使用されている場所に html を追加します。

body タグの直前に追加するようにライターに指示する方法はありますか?

また、コンポーネントの本体を取得するにはどうすればよいですか?

4

3 に答える 3

1

そこまで複雑にする必要はないと思う

@Environmental
private Heartbeat heartbeat;

@SetupRender
void setupRender(MarkupWriter writer) {
    writer.element("div");
}

// let the body render as normal

@AfterRender
void afterRender(final MarkupWriter writer) {
    Element wrapper = writer.element();
    writer.end();
    final String bodyMarkup = wrapper.getChildMarkup();

    // remove the body 
    wrapper.remove();

    heartbeat.defer(new Runnable() {
        public void run() {
            Element pageBody = writer.getDocument().find("html/body");
            pageBody.raw(bodyMarkup);
        }
    });
}
于 2013-01-22T20:59:25.333 に答える
0

ソリューション:

    private Element pageBody;
    private String componentBodyMarkup;
    private Element wrapper;

    @Environmental
    private Heartbeat heartbeat;

    @SetupRender
    private RenderCommand setupRender() {
        return new RenderCommand() {
            public void render(MarkupWriter writer, RenderQueue queue) {
                wrapper = writer.element("div");

                RenderCommand renderBody = new RenderCommand() {
                    public void render(MarkupWriter writer, RenderQueue queue2) {
                        RenderCommand bodyRenderCommand = typeCoercer.coerce(componentResources.getBody(), RenderCommand.class);
                        queue2.push(bodyRenderCommand);
                    }
                };
                queue.push(renderBody);
            }
        };
    }

    @BeforeRenderBody
    private boolean beforeRenderBody(MarkupWriter writer) {
        return false;
    }

    @AfterRender
    private void afterRender(MarkupWriter writer) {
        pageBody = writer.getDocument().find("html/body");

        writer.end();

        componentBodyMarkup = wrapper.getChildMarkup();
        wrapper.remove();

        Runnable appendToBody = new Runnable() {
            public void run() {
                pageBody.raw(componentBodyMarkup);
            }
        };
        heartbeat.defer(appendToBody);
    }
于 2013-01-22T19:21:21.047 に答える
0

コンポーネントの本体を取得するには、@Inject ComponentResources を呼び出して getBody() を呼び出す必要があります。

ボディの最後に何かを追加するには、もう少し考える必要があります。私は2つの方法を見ることができます。

@HeartbeatDeferred アノテーションを使用すると、他のすべてのコンポーネントがレンダリングされた後に DOM にアクセスできます。このようなもの:

public class MyComponent {
    private Element body;

    void setupRender(MarkupWriter writer) {
        body = writer.getDocument().find("html/body");
    }

    @HeartbeatDeferred
    void addToBody() {
        body.text("Some text here");
    }
}

もう 1 つの方法は、他のすべてのコンポーネントをネストする body タグの直下にコンポーネントを定義することです。このコンポーネントは、 @SetupRender メソッドでモデル オブジェクトを環境にプッシュします。最上位コンポーネントの子として定義されたコンポーネントは、 @Environmental アノテーションを使用してモデル オブジェクトを検索し、それに貢献できます。次に、最上位のコンポーネントがモデルをレンダリングします。

例えば:

<html>
   <body>
       <t:toplevelcomponent>
          <t:childcomponent />
          <div>...</div>
          <div>...</div>
       </t:toplevelcomponent>
   </body>
</html>

public class TopLevelModel {
    private List<String> contributions;

    // getters and setters
}

public class TopLevelComponent {
      @Inject
      Environment environment;

      public void setupRender() {
          environment.push(TopLevelModel.class, new TopLevelModel());
      }

      public void afterRender(MarkupWriter writer) {
          TopLevelModel model = environment.pop(TopLevelModel.class);
          for (String contribution : model.getContributions()) {
              // add text to the body tag
              writer.getElement().text(contribution); 
          }
      }
}

public class ChildComponent {
      @Environmental
      private TopLevelModel topLevelModel;

      public void setupRender() {
           topLevelModel.getContributions().add("Foo");
           topLevelModel.getContributions().add("Bar");
      }
}
于 2013-01-21T22:19:12.617 に答える