0

メイン アプリケーション (Flex 4.6) があり、このアプリケーションで任意の数のウィジェットを使用する予定です。ウィジェットは .swf ファイルです (s:Module または s:Application、Flex 4.6)。

私の問題は、読み込まれたウィジェットが、それを使用しているアプリケーションのスタイルを継承しないことです。

簡単に言うと、(URLLoader クラスを使用して) サーバーからウィジェットを .swf ファイルとしてロードします。それをダウンロードした後、ウィジェットのインスタンスを作成します (一方、単一のウィジェットは、複数のさまざまな場所のメイン アプリケーションで共有できます - 乗算します)。

メイン アプリケーションでは、次の CSS ファイルが使用されます。

<fx:Style source="css/common.css" />

common.css の内容は次のとおりです。

s|TextInput {
   contentBackgroundColor: #9FD1F2;
   focusColor: #8FD7F9;
   skinClass: ClassReference("skins.textInputTestSkin");
}


s|Label {
   color: #2211FF;
}

これがウィジェットを作成してロードする方法です。

private var bytesLoader:Loader = null;
public var loadedApp:SystemManager = null;
public var loadedModule:Module = null;

...

bytesLoader.addEventListener(Event.COMPLETE, onBytesLoaderComplete);
var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
bytesLoader.loadBytes(urlLoader.data, context);

...


private function onBytesLoaderComplete(e:Event):void {
   var dataContent:DisplayObject = bytesLoader.content;

   //(Application)
   if(dataContent && (dataContent is SystemManager)) {
      loadedApp = dataContent as SystemManager;
      loadedApp.addEventListener(FlexEvent.APPLICATION_COMPLETE,appWidgetCreationComplete);

      appHolder.addChild(dataContent);
   } else if(dataContent is IFlexModuleFactory) {
      //(Module)
      var moduleLoader:LoaderInfo = LoaderInfo(e.target);
      moduleLoader.content.addEventListener("ready", moduleWidgetReadyHandler);
   }
}



private function moduleWidgetReadyHandler(e:Event):void {
   var factory:IFlexModuleFactory = IFlexModuleFactory(e.target);
   if(factory) {
      loadedModule = factory.create() as Module;

      if(loadedModule) {
         this.addElement(loadedModule);
      }
   }
}

私の質問は、最初に、親のスタイルをウィジェットにどのように適用できますか (s:Module)、親のスタイルをウィジェットにどのように適用できるか (s:Application) です。 .

更新 1

すべてのウィジェットで getter moduleFactory (以下を参照) を変更すると、スタイルが適切に設定されます。つまり、ウィジェット (モジュールとアプリケーション) の textInput には、メイン アプリケーションと同じスキンがあります。

override public function get moduleFactory():IFlexModuleFactory {
   return FlexGlobals.topLevelApplication.moduleFactory;
}  

それは回避策ですか?それは良い解決策ですか?

4

1 に答える 1

0

わかりました、ここに解決策があります:

bytesLoader.loadBytes(urlLoader.data, context); の前に追加します。

    //init - moduleFactory
    bytesLoader.contentLoaderInfo.addEventListener(Event.INIT, onContentLoaderInfoInit);


    private function onContentLoaderInfoInit(e:Event):void {
        if(bytesLoader && bytesLoader.contentLoaderInfo) {
            bytesLoader.contentLoaderInfo.removeEventListener(Event.INIT, onContentLoaderInfoInit);
        }

        var loaderInfo:LoaderInfo = LoaderInfo(e.target);
        loaderInfo.content.addEventListener(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST, onGetParentModuleFactoryRequest);
    }


    private function onGetParentModuleFactoryRequest(r:Request):void {
        if(isGlobalStyleAllowed) {
            if ("value" in r) {
                r["value"] = FlexGlobals.topLevelApplication.moduleFactory;
            }
        }

        //remove eventListener
        if(bytesLoader && bytesLoader.contentLoaderInfo) {
            var loaderInfo:LoaderInfo = LoaderInfo(bytesLoader.contentLoaderInfo);
            loaderInfo.content.removeEventListener(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST, onGetParentModuleFactoryRequest);
        }
    }

それは動作します。

于 2013-04-11T08:20:58.977 に答える