GWT, CssStyle вводится несколько раз

Я использую ClientBundle и CssResources уже довольно давно, но заметил, что мои стили вводятся много раз. Единственное, что я могу указать пальцем, это то, что я использую немало <ui:with field='resources' type='com.vf.client.resources.Resources' /> в моих шаблонах, и я подозреваю, что это создает несколько копий моего clientBundle. Одна вещь, которая может даже вызвать это, заключается в том, что я использую концепцию Рэя Райана для кэширования моих представлений в моей клиентской фабрике, поэтому некоторые представления создаются еще до того, как они были присоединены к DOM. В моем базовом представлении я использую обеспеченный =true для ресурсов, чтобы, надеюсь, не позволить UiBinder сгенерировать новый для меня. Это может не сработать, хотя, я подозреваю, и пользовательский интерфейс создает новую копию и игнорирует предоставленный =true. Я использовал инструменты разработчика в Chrome и Firebug, чтобы увидеть, и в обоих случаях стиль вводится много раз. Не уверен, как решить эту проблему, не удаляя мой класс Resources из всех моих шаблонов UiBinder, и это потребует немало усилий. Любые идеи приветствуются.

/**
 * 
 * @author chris
 */
public abstract class ViewImpl extends Composite implements IView, RequiresResize {

    @UiField(provided = true)
    public final Resources resources;

}




public interface Resources extends ClientBundle, CellTable.Resources, CellList.Resources, DataGrid.Resources {

    /**
     * These are the obfuscated styles.
     * 
     * @return
     */
    @Source({ "default.css", "default-external.css"})
    public Style style();
}

Обновить

Я использовал factory / singleton только для того, чтобы убедиться, что он создает только один. Я создаю этот ресурс ClientBundle в своей реализации ClientFactory при запуске приложения. При запуске приложения я вызываю sureEnjected в моем стиле, и с этого момента в моем коде никогда не вызывается sureInjected.

Это моя фабрика, которая просто получает мою фабрику по запросу. Раньше у меня был статический инициализатор в моем интерфейсе, но я перешел к этому некоторое время назад, чтобы, надеюсь, решить мою проблему с несколькими стилями.

import com.google.gwt.core.client.GWT;

public class ResourcesFactory {

    private static Resources instance = null;

    private ResourcesFactory() {
    }

    public static final Resources getResources() {
        if (instance == null) {
            instance = GWT.create(Resources.class);
        }

        return instance;
    }
}

Мой клиентский пакет инициализируется и вводится только здесь.

  @Override
    public void onModuleLoad() {
        if (Window.Location.getParameterMap().containsKey("debug")) {
            Window.alert("Remote Debugging will be enabled, see server log for debug information");
            RemoteDebugService.enable();    
        }

        try {
            clientFactory = ClientFactory.INSTANCE;
            masterLayoutPanel = clientFactory.getMasterLayoutPanel();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Unable to instantiate the ClientFactory", e);
            Window.alert("SOMEBODY BROKE THE BUILD, add ?debug to the url to enable remote debugging" + e.getMessage());
        }

        RootLayoutPanel.get().add(masterLayoutPanel);
        StyleInjector.inject(clientFactory.getResources().style().getText());

        PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(clientFactory.getPlaceHistoryMapper());
        PlaceController placeController = clientFactory.getPlaceController();

        // Start PlaceHistoryHandler with our PlaceHistoryMapper
        historyHandler.register(placeController, clientFactory.getEventBus(), defaultPlace);

        startApplication(clientFactory, historyHandler);
        }

2 ответа

Решение

Я понял, по крайней мере, одну проблему, которую я до сих пор делал неправильно, которая заставляла мой стиль вводиться несколько раз. Во-первых, я определил, что мои стили CellTable и Datagrid должны быть внутри моей отдельной таблицы стилей, но при внедрении этого стиля он вводится несколько раз. В приведенном ниже коде файл default.css содержит все мои определения CSS для всего веб-приложения, включая таблицу ячеек и стили сетки ячеек. Я внедрял их при запуске приложения, конечно, cellTableStyle() и cell dataGridStyle() внедряют всю таблицу стилей.

public interface Resources extends ClientBundle, CellTable.Resources, CellList.Resources, DataGrid.Resources {

...

    /**
     * {@link CellTable.Style} styles
     */
    @Source("default.css")
    Style cellTableStyle();

    /**
     * {@link DataGrid.Style} styles
     */
    @Source("default.css")
    Style dataGridStyle();

    /**
     * These are the obfuscated styles.
     * 
     * @return
     */
    @Source({ "default.css", "default-external.css" })
    public Style style(); 
...


}

Если декларировать стили таким образом, таблицы стилей должны быть разбиты на отдельные таблицы стилей и содержать только соответствующие стили или реализовывать мой основной стиль для реализации этих интерфейсов и удаления дополнительных зависимых реализаций стилей.

public interface Resources extends ClientBundle, CellTable.Resources, CellList.Resources, DataGrid.Resources {

...



    /**
     * {@link CellTable.Style} styles
     */
    @Source("celltable.css")
    Style cellTableStyle();

    /**
     * {@link DataGrid.Style} styles
     */
    @Source("datagrid.css")
    Style dataGridStyle();

    /**
     * These are the obfuscated styles.
     * 
     * @return
     */
    @Source({ "default.css", "default-external.css" })
    public Style style(); 
...


}

Это реализация, в которой стиль может быть передан стилю CellTable, а стили будут внедрены только один раз. Обратите внимание, что стиль включает в себя все необходимые стили таблицы, сетки и списка.

public interface Resources extends ClientBundle, CellTable.Resources, CellList.Resources, DataGrid.Resources {

...

 public interface Style extends CssResource, ProgressWidget.Style, CellTable.Style, CellList.Style, DataGrid.Style {
    ...

}


    /**
     * Single style that can be used for all my cell table resources 
     * and the default styles.
     * 
     * @return
     */
    @Source({ "default.css", "default-external.css" })
    public Style style(); 
...


}

Что вы имеете в виду именно под инъекцией несколько раз?

ClientBundle - это, в основном, Singleton (см. Эту ветку. Будет ли ссылка на один класс ClientBundle из нескольких UiBinder стоить что-нибудь?).
Так что это даже не имеет значения, если вы используете provided=true или нет.

Но если вы действительно хотите избежать даже прокси ClientBundle, вы можете использовать Gin или Factory создать экземпляр (GWT.create или магически через @Inject) ClientBundle один раз и введите его в свой Views но я думаю, что в скомпилированном коде это не будет иметь большого значения.

Другие вопросы по тегам