如何使您的GWT应用程序可插入?

aju*_*ine 5 gwt plugins

我正在(与我的团队一起)编写一个GWT应用程序,它解析并表示一些特定于域的语言 - 例如,播放带有文本,视频和UI控件的媒体演示.因此,应用程序有一组组件:1 - 用于保存模型,1用于控制例程(控制器),当然我们有View类.

现在我们遇到了一个问题 - 在以下意义上使其全部可插拔:

  • 应该是一个核心插件,它使所有常见的东西.这个coer块必须是一个JavaScript文件(每个排列一个)

  • 应该能够扩展核心类,编写自定义类 - 并将其编译为单独的JS文件(每个排列一个)

每个插件必须注册(导出它的类等)本身到核心平台,因此可以使用它.

问题:

  1. 如何单独编译自定义的东西?
  2. 如何加载插件?

对于第二问题,我找到了http://code.google.com/p/gwt-exporter/,它将GWT类导出到外部世界,因此可以从纯JS调用它们.

此外,我有一个想法为新插件创建新模块,因此它将被编译为单独的文件(第一个问题).

您是否有构建此类架构的经验,在这种情况下,您有一些最佳实践吗?

LIN*_*N78 3

自 GWT 1.5 以来,我一直在尝试解决同样的问题,每次我想出更优雅的解决方案时,他们都会更改链接器并破坏它。我想出的独立于链接器设计的唯一方法是完全按照您所说的进行操作,并为所有插件创建一个新模块。然后使用 GWT 导出器创建一个插件必须扩展的抽象类,该类具有一个抽象方法,该方法将获取由核心传递给它的插件的根元素并填充它。此方法的问题是,所有插件模块都必须在页面初始加载时添加到 DOM,因为从 2.0 开始,iFrame 链接器依赖于页面加载事件,因此动态添加的模块将无法完全加载。因此,您需要将导出的填充方法封装在 runAsync 中,以便在使用模块之前不会下载它们。

编辑:

这是我正在谈论的内容的一个粗略示例。请注意,我已经有几年没有做过任何 GWT 了,现在可能有更好的方法来做到这一点。

public final class PluginManager
{
    public static final PluginManager INSTANCE = new PluginManager();

    private PluginManager()
    {
    }

    private static native void loadPlugin( AbstractPlugin plugin )
    /*-{
        if (!$wnd.Plugins) {
            $wnd.Plugins = {};
        }
        var name = plugin.@com.example.PluginManager.AbstractPlugin::getName()();
        $wnd.Plugins[name] = $entry(plugin.@com.example.PluginManager.AbstractPlugin::load(Ljava/lang/String;));
    }-*/;

    private static native void unloadPlugin( AbstractPlugin plugin )
    /*-{
        if ($wnd.Plugins) {
            var name = plugin.@com.example.PluginManager.AbstractPlugin::getName()();
            delete $wnd.Plugins[name];
        }
    }-*/;

    private static native JsArrayString getPlugins()
    /*-{
        if ($wnd.Plugins) {
            return Object.keys($wnd.Plugins);
        }
        return undefined;
    }-*/;

    public static abstract class AbstractPlugin implements EntryPoint
    {
        @Override
        public final void onModuleLoad()
        {
            PluginManager.INSTANCE.loadPlugin( this );
        }

        protected final void unload()
        {
            PluginManager.INSTANCE.unloadPlugin( this );
        }

        protected abstract String getName();

        protected abstract void load( String rootPanelId );
    }
}
Run Code Online (Sandbox Code Playgroud)