I have been using a ClientBundle and CssResources for quite some time but have noticed that my styles is getting injected many times. The one thing I can point my finger too is that I use quite a few <ui:with field='resources' type='com.vf.client.resources.Resources' />
in my templates and my suspicion is that this is creating multiple copies of my clientBundle. One thing that may even cause this is that I use Ray Ryan's concept of caching my views in my clientfactory so some of the views are created before ever being attached to the DOM. In my base view I use the provided=true on the resources so as to hopefully not let UiBinder generate a new one for me. This may not be working though, I am suspecting and the ui:with is creating a new copy and ignoring the provided=true. I have used developer tools in Chrome and Firebug to see and in both cases the style is getting injected many times. Not sure on how to even resolve this problem without removing my Resources class from all my UiBinder templates and this would make for quite a bit of work. Any ideas are appreciated.
/**
*
* @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();
}
Update
I have been using a factory/singleton just to make sure it only creates one. I create this Resources ClientBundle in my ClientFactory implementation when the application starts. In my application start I call ensureEnjected on my style and from then on the ensureInjected is never called in my code.
This is my factory that simply gets my singleon request factory. I used to have the static initializer inside my interface but I moved to this a while back to hopefully clean up my multiple styles problem.
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;
}
}
My client bundle gets initialized and injected here only.
@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);
}