gpt4 book ai didi

gwt - ClientBundle 为多个 "themes"

转载 作者:行者123 更新时间:2023-12-04 05:26:37 26 4
gpt4 key购买 nike

我们有一个 Web 应用程序,它需要为每个主要客户提供不同的主题。最初的开发人员通过查看 javascript 中的 URL 并添加样式表来覆盖默认主题来做到这一点。

这样做的一个问题是该站点具有几秒钟的默认外观,然后突然切换到正确的主题。另一个是它似乎浪费了大量的带宽/时间。

我目前的想法是创建一个“默认”ClientBundle使用我们的默认外观扩展该界面并使用客户端图像覆盖每个条目(根据需要),使用各种注释(如@ImageResouce)并指向不同的位置。

有没有人有这样做的经验?我预见到的一个问题是无法使用 uibinder 样式标签,因为它们静态指向特定的资源包。

有任何想法吗?

最佳答案

被覆盖的包

是的你可以。

我已经用 ClientBundles 做了覆盖的事情并且工作正常。您必须做的一件事是也继承属性的类型。举例:

BigBundle {
Nestedundle otherBundle();
ImageResource otherImage();
Styles css();
}

然后你必须以这种方式继承:
OtherBigBundle extends BigBundle {
OtherNestedBundle otherBundle(); // if you want to change it
ImageResource otherImage(); // of you want to change it
OtherStyles css(); // of you want to change it
}

OtherNestedBundle extends NestedBundleOtherStyles extends Styles
至少使用 css 的:如果属性声明为不使用子接口(interface),它们将为相同的 CSS 类名生成样式,并且所有样式都将混合在一起。所以用子接口(interface)声明覆盖样式:)

灵活的 UIBinders

如果您使用 UiField(provided=true),则可以从捆绑包外部设置使用注解。这样,您首先设置捆绑包,然后调用 uibindler。假设它已经创建,它将使用资源字段。

延迟绑定(bind)

您可以使用 GWT.runAsync 来加载正确的包。

一些例子

ui.xml
<ui:with field='res' type='your.package.TheBundle'/>

对应的类
@UiField(provided=true) TheBundle bundle;

private void createTheThing() {
this.bundle = factory.createBundle();
MyUiBindler binder = GWT.create(MyUiBindler.class);
this.panel = binder.createAndBindUi(this);
...
}

一些捆绑接口(interface)
interface TheBundle extends ClientBundle {
@ImageResource("default.png")
ImageResource image1();

@Source("default.css")
TheCss css();
}

interface Theme1Bundle extends TheBundle {
@ImageResource("one.png")
ImageResource image1(); // type: imageresource is ok

@Source("one.css")
OneCss css(); // type: OneCss => use other compiled css class-names

interface OneCss extends TheCss { // inner-interface, just for fun
// don't need to declare each String method
}
}

如果您不覆盖某些内容,则可以

捆绑工厂的选项

1) 完全
if (...) {
return GWT.create(TheBundle.class);
} else if (...) {
return GWT.create(Theme1Bundle.class);
}

2)runAsync(只需加载所需的部分......但在执行初始部分之后)
if (...) {
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
return GWT.create(TheBundle.class);
}
// please program the onFailure method
});
} else if (...) {
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
return GWT.create(Theme1Bundle.class);
}
// please program the onFailure method
});
}

3) 使用延迟绑定(bind)和生成器在编译时基于带注释的捆绑包(如 @ThemeBundle("one"))自动生成工厂

这个例子来自现实世界。我使用 DynamicEntryPointWidgetFactory(简称 DEPWidgetFactory)基于标识符字符串创建小部件。每个小部件都是一个应用程序屏幕,每个主菜单项都有它必须创建的小部件名称。

在您的情况下, id 将是要创建的主题。

重要提示:如果您使用 runAsync,则无法像之前的示例代码那样在创建 UI 之前创建资源包。您必须询问主题,并且当它准备好时(在回调中)将其传递给您的小部件构造函数,您的小部件可以将其分配给它的字段。

工厂界面:
public interface DynamicEntryPointWidgetFactory
{
public void buildWidget(String widgetName, AsyncCallback<Widget> callback);
}

要生成的小部件的注释:
@Target(ElementType.TYPE)
public @interface EntryPointWidget
{
/**
* The name wich will be used to identify this widget.
*/
String value();
}

模块配置:

它说:工厂的实现将使用这个类生成(另一个选项是使用替换,但在我们的例子中,我们没有为每个语言环境或浏览器预定义选项,而是更动态的)。
<generate-with class="com.dia.nexdia.services.gwt.rebind.entrypoint.DynamicEntryPointFactoryGenerator">
<when-type-assignable class="com.dia.nexdia.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactory" />
</generate-with>

生成器:
public class DynamicEntryPointFactoryGenerator extends Generator {
@Override
public String generate(TreeLogger logger, GeneratorContext context,
String typeName) throws UnableToCompleteException {
PrintWriter pw = context.tryCreate(logger,
"x.services.gwt.client.entrypoint",
"DynamicEntryPointWidgetFactoryImpl");

if (pw != null) {
// write package, imports, whatever
pw.append("package x.services.gwt.client.entrypoint;");
pw.append("import x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactory;");
pw.append("import com.google.gwt.core.client.GWT;");
pw.append("import com.google.gwt.core.client.RunAsyncCallback;");
pw.append("import com.google.gwt.user.client.rpc.AsyncCallback;");
pw.append("import com.google.gwt.user.client.ui.Widget;");

// the class
pw.append("public class DynamicEntryPointWidgetFactoryImpl implements DynamicEntryPointWidgetFactory {");

// buildWidget method
pw.append(" public void buildWidget(String widgetName, final AsyncCallback<Widget> callback) {");

// iterates over all the classes to find those with EntryPointWidget annotation
TypeOracle oracle = context.getTypeOracle();
JPackage[] packages = oracle.getPackages();
for (JPackage pack : packages)
{
JClassType[] classes = pack.getTypes();
for (JClassType classtype : classes)
{
EntryPointWidget annotation = classtype.getAnnotation(EntryPointWidget.class);
if (annotation != null)
{
String fullName = classtype.getQualifiedSourceName();
logger.log(TreeLogger.INFO, "Entry-point widget found: " + fullName);

pw.append("if (\"" + annotation.value() + "\".equals(widgetName)) {");
pw.append(" GWT.runAsync(" + fullName + ".class, new RunAsyncCallback() {");
pw.append(" public void onFailure(Throwable t) {");
pw.append(" callback.onFailure(t);");
pw.append(" }");
pw.append(" public void onSuccess() {");
pw.append(" callback.onSuccess(new " + fullName + "());");
pw.append(" }");
pw.append(" });");
pw.append(" return;");
pw.append("}");
}
}
}
pw.append("callback.onFailure(new IllegalArgumentException(\"Widget '\" + widgetName + \"' not recognized.\"));");

pw.append(" }");
pw.append("}");

context.commit(logger, pw);
}

// return the name of the generated class
return "x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactoryImpl";
}

关于gwt - ClientBundle 为多个 "themes",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5709298/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com