gwt - 如何通过 GIN 与 UiBinder 和小部件一起使用注入(inject)?

标签 gwt dependency-injection uibinder gwt-gin

我将 GWT 2.4 与 gwt-platform 0.7 和 gin 1.5.0 一起使用。

我已经为我的 GWT 应用程序的动态(实时)翻译构建了一个库。因此,当 LocaleChangeEvent 出现时,每个小部件都会收到通知。被解雇然后问我的TranslationDictionary获取要显示的新字符串。

小部件实际上如下所示:

public class LocaleAwareLabel extends Label implements LocaleChangeEventHandler {
    TranslationDictionary dictionary;
    String translationToken;

    public LocaleAwareLabel(TranslationDictionary dictionary, EventBus eventBus, String translationToken) {
        this.dictionary = dictionary;
        this.translationToken = translationToken;
        eventBus.addHandler(LocaleChangeEvent.TYPE, this);
        getCurrentTranslationFromDictionary();
    }

    public void getCurrentTranslationFromDictionary() {
        this.setText(dictionary.getTranslation(translationToken));
    }

    @Override
    public void onLocaleChange(LocaleChangeEvent event) {
        getCurrentTranslationFromDictionary();
    }
}

正如你所看到的:我不能轻易地在 UiBinder 中使用这个小部件,目前我注入(inject) EventBusTranslationDictionary在我的View并使用 @UiField(provided=true)像这样:
@UiField(provided=true)
LocaleAwareLabel myLabel;

@Inject
public MyView(TranslationDictionary dictionary, EventBus eventBus) {
    widget = uiBinder.createAndBindUi(this);

    myLabel = new LocaleAwareLabel(dictionary, eventBus, "someTranslationToken");
}

我想要的:在没有 @UiField(provided=true) 的情况下使用我的小部件,所以我可以简单地将它们放在 ui.xml 中像这样:
<custom:LocaleAwareLabel ui:field="myLabel" translationToken="someTranslationToken" />

我知道我可以设置 translationToken通过 UiBinder 使用:
public void setTranslationToken(String translationToken) {
    this.translationToken = translationToken;
}

但是我仍然有一个问题,因为 EventBus,我不能使用零参数构造函数。和 TranslationDictionary .另外我不能调用getCurrentTranslationFromDictionary()在构造函数内部,因为 translationToken 的值当然在构造函数之后设置。

如果有人可以提供解决方案,也许还有代码示例,那就太好了。

P.S.我是一个完全的注入(inject)菜鸟,但据我了解, Gin 可能会以某种方式解决我的问题。但我不知道怎么做。

谢谢!

最佳答案

目前依赖注入(inject)和 UiBinder 之间存在一些概念上的不匹配,但我目前使用它的方式是:

private final Provider<LocaleAwareLabel> labelProvider;

@Inject
public MyView(TranslationDictionary dictionary, 
              EventBus eventBus, 
              Provider<LocaleAwareLabel> labelProvider) {

  this.dictionary = dictionary;
  this.labelProvider = labelProvider;
  initWidget(uiBinder.createAndBindUi(this));
}

@UiFactory
public LocaleAwareLabel buildLocaleAwareLabel() {
  return labelProvider.get();
}

然后我可以在 ui.xml 中创建任意数量的标签:

<g:HTMLPanel>
  <custom:LocaleAwareLabel translationToken="abc"/>
  <custom:LocaleAwareLabel translationToken="xyz"/>
</g:HTMLPanel>

在 LocaleAwareLabel 中,我对翻译标记使用 setter 方法,并覆盖 onLoad() :

private String translationToken;

@Inject
public LocaleAwareLabel(TranslationDictionary dictionary, EventBus eventBus) {
  this.dictionary = dictionary;
  initWidget(uiBinder.createAndBindUi(this));
}

@Override
protected void onLoad() {
  super.onLoad();
  doSomethingWithTheTranslationToken(); // do this here, not in the constructor!
}

public void setTranslationToken(final String translationToken) {
  this.translationToken = translationToken;
}

AssistedInject 示例

MyView 更改为:

private final LocaleAwareLabelFactory labelFactory;

@Inject
public MyView(TranslationDictionary dictionary, 
              EventBus eventBus, 
              LocaleAwareLabelFactory labelFactory) {

  this.dictionary = dictionary;
  this.labelFactory = labelFactory;

  initWidget(uiBinder.createAndBindUi(this));
}

@UiFactory
public LocaleAwareLabel buildLocaleAwareLabel(final String translationToken) {
  return labelFactory.create(translationToken);
}

区域感知标签:

public interface LocaleAwareLabelFactory {
  LocaleAwareLabel create(final String translationToken);
}

@Inject
public LocaleAwareLabel(TranslationDictionary dictionary, 
                        EventBus eventBus, 
                        @Assisted String translationToken) {

  this.dictionary = dictionary;
  initWidget(uiBinder.createAndBindUi(this));
  doSomethingWithTheTranslationToken(); // now you can do it in the constructor!
}

在您的 Gin 模块中,添加:

install(new GinFactoryModuleBuilder().build(LocaleAwareLabelFactory.class));

确保将 guice 的辅助注入(inject) jar(例如 guice-assistedinject-snapshot.jar)添加到您的类路径中。

关于gwt - 如何通过 GIN 与 UiBinder 和小部件一起使用注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11434346/

相关文章:

java - gwt maven编译不生成入口点html文件

java - GWTP Rest Dispatch 可以与 REST Spring 服务器后端一起使用吗?

css - smartgwt 样式

java - 从字节数组中编码字符串问题

gwt - 如何: UiBinder + GWT MVP + multiple independent display areas

gwt - 从多个 UiBinders 引用单个 ClientBundle 类是否会花费任何费用?

frameworks - 框架时代的封装

Delphi,如何避免application.CreateForm?

php - 将对象传递给 Laravel 中间件

java - 以编程方式从 LocalizedResource.properties 中读取 key