8

私はgwt-platform0.7とgin1.5.0でGWT2.4を使用しています。

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で簡単に使用することはできません。現時点では、インジェクトして次のEventBusよう に使用TranslationDictionaryしています。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

誰かがおそらくコード例で解決策を提供できればいいのにと思います。

そしてPS私は完全な注射初心者ですが、私の理解から、ジンはどういうわけか私の問題を解決するかもしれません。しかし、私は方法がわかりません。

ありがとうございました!

4

2 に答える 2

6

現在、依存性注入と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);
}

LocaleAwareLabel:

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のassistedinjectjar(guice-assidedinject-snapshot.jarなど)をクラスパスに追加してください。

于 2012-07-11T15:38:28.903 に答える
5

UiBinderがウィジェットをインスタンス化するためにGINを呼び出すことはないため、これは現在不可能です。そのためには、@UiFactoryメソッドを使用するか、ビルド済みのインスタンスに。を指定する必要があります@Uifield(provided=true)

2つをよりよく統合するために、すでに拡張の要求があります。ここで追跡できます:http ://code.google.com/p/google-web-toolkit/issues/detail?id = 6151

別の方法として、フィールドにaを挿入し、コンストラクター内からプロバイダーを呼び出すことrequestStaticInjectionができます 。Providerstaticget()

public class LocaleAwareLabel extends Label {
   @Inject Provider<EventBus> eventBusProvider;
   @Inject Provider<TranslationDictionary> dictionaryProvider;

   private final TranslationDictionary dictionary;
   private final EventBus eventBus;
   private final string translationToken;

   @UiConstructor
   public LocaleAwareLabel(String translationToken) {
       this(dictionaryProvider.get(), eventBusProvider.get(), translationToken);
   }

   // For cases where you can use injection, or inject params yourself
   @Inject
   public LocaleAwarelabel(TranslationDictionary dictionary, EventBus eventBus,
           String translationToken) {
       this.dictionary = dictionary;
       this.eventBus = eventBus;
       this.translationToken = translationToken;
   }

@UiFactoryメソッドの記述や@UiField(provided=true)フィールドの初期化を容易にするために、GINのAssisted-Injectのサポートにも興味があるかもしれません。

于 2012-07-11T15:01:23.377 に答える