我已经看过许多关于通过MarkupWriter以编程方式添加html的教程,但它添加了使用该组件的html。
有没有办法告诉作者在关闭身体标签之前添加它?
另外,我如何获得组件的主体?
答案 0 :(得分: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);
}
});
}
答案 1 :(得分:0)
要获取组件的主体,您应该@Inject ComponentResources并调用getBody()。
要在身体末端添加一些东西需要稍微多想一想。我可以看到两种方式。
使用@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");
}
}
另一种方法是直接在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");
}
}
答案 2 :(得分: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);
}