2010-02-04 79 views
1

我有一個XML,它有一個屬性選項或組合框,解析我需要動態地在我的flex中創建組件。從XML創建Flex組件

Viatropos給予了美好的代碼,但我不能夠執行它...任何人都可以生產它...感謝

+1

你需要問一個問題... – Simon 2010-02-04 10:07:49

+0

我想創建一個閱讀XML的組件 – Kevin 2010-02-04 10:31:43

回答

10

您可以創建Flex組件動態像這樣的東西:

樣本數據

<?xml version="1.0" encoding="UTF-8"?> 
<components type="array"> 
    <component type="mx.controls.ComboBox"> 
     <width>100</width> 
     <height>100</height> 
     <color isStyle="true">0xff0000</color> 
     <prompt>Im a Combo Box!</prompt> 
    </component> 
    <component type="mx.controls.Button"> 
     <width>100</width> 
     <height>100</height> 
     <color isStyle="true">0xff0000</color> 
     <label>Im a Button!</label> 
    </component> 
</components> 

示例應用程序

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    creationComplete="creationCompleteHandler()"> 

    <mx:Script> 
     <![CDATA[ 

      import flash.display.DisplayObject; 
      import mx.core.UIComponent; 
      import mx.controls.ComboBox; ComboBox; 

      protected function creationCompleteHandler():void 
      { 
       var components:Array = getComponentsFromXML(xml.component); 
       var i:int = 0; 
       var n:int = components.length; 
       for (i; i < n; i++) 
       { 
        panel.addChild(components[i] as DisplayObject); 
       } 
      } 

      /** 
      * Parses an XML string, returns array of new components. 
      */ 
      public function getComponentsFromXML(components:XMLList):Array 
      { 
       var result:Array = []; 
       var child:Object; 
       var component:UIComponent; 
       var type:String; 
       var clazz:Class; 
       var i:int = 0; 
       var n:int = components.length(); 
       for (i; i < n; i++) 
       { 
        child = components[i]; 
        type = [email protected]; 
        try { 
         clazz = flash.utils.getDefinitionByName(type) as Class; 
        } catch (error:ReferenceError) { 
         traceImportError(type); 
        } 

        component = new clazz(); // dynamic 

        var properties:XMLList = child.elements(); 
        var property:XML; 
        var name:String; 
        var value:Object; 

        // for each child node 
        for each (property in properties) 
        { 
         name = property.localName(); 
         value = property.toString(); 
         // create a more generic method to convert 
         // strings to numbers and whatnot 
         // this is a regular expression matching any digit 
         // check out rubular.com 
         if (/\d+/.test(value.toString())) 
          value = Number(value); 

         if (property.attribute("isStyle") == "true") 
          component.setStyle(name, value); 
         else 
          component[name] = value; 
        } 
        result.push(component); 
       } 
       return result; 
      } 

      protected function traceImportError(type:String):void 
      { 
       trace("Please include the class '" + type + "' in the swf."); 
       var names:Array = type.split("."); 
       var last:String = names[names.length - 1]; 
       trace("import " + type + "; " + last + ";"); 
      } 

     ]]> 
    </mx:Script> 

    <!-- sample data --> 
    <mx:XML id="xml" source="components.xml" /> 

    <!-- sample container --> 
    <mx:Panel id="panel" width="100%" height="100%"/> 

</mx:Application> 

只要您爲XML定義了結構,就可以創建一個用於一般處理xml(例如獲取所有屬性或將字符串轉換爲正確類型)的XMLUtil,以及一個ComponentManifest類XML文件並將其轉換爲組件。

您還需要確保所有在XML中定義的類都被導入到swf中,否則會拋出該錯誤。你能做到這一點,像這樣:

import mx.controls.ComboBox; ComboBox;

直進口,而沒有第二ComboBox不會去做。

這應該讓你開始,根據需要填寫它!

檢出Rubular如果您想要更好/高級的xml值解析,請使用Regular Expressions

+0

你能提供給我完整的代碼嗎我得到一些錯誤 – Kevin 2010-02-04 11:10:04

+0

@viatropos:謝謝你的回答,我只是傾斜今天有新東西:) – 2010-02-15 06:15:43

+0

今天我剛剛學到了一些新東西[2] :) – MysticEarth 2010-02-16 09:47:59

2

這裏是@ viatropos的解決方案修改的版本:

樣本數據:

<?xml version="1.0" encoding="UTF-8"?> 
<components type="array"> 
    <component type="mx.controls::ComboBox"> 
     <width>100</width> 
     <height>100</height> 
     <color isStyle="true">"0xff0000"</location> 
     <label>"Im a Combo Box!"</label> 
    </component> 
    <component type="mx.controls::Button"> 
     <width>100</width> 
     <height>100</height> 
     <color isStyle="true">"0xff0000"</location> 
     <label>"Im a Button!"</label> 
    </component> 
</components> 

這裏顯然有其中使用結束標籤的錯誤。

我還在所有字符串值周圍添加了引號,以便於識別它們。

樣品(僞)方法:createComponentsFromXML(xml.components)

public function createComponentsFromXML(components:XMLList):void 
{ 
    var child:Object; 
    var component:UIComponent; 
    var i:int = 0; 
    var n:int = components.length(); 
    for (i; i < n; i++) 
    { 
     child = components[i]; 
     var clazz:Class = flash.utils.getDefinitionByName([email protected]); 
     component = new clazz(); // dynamic 
     var property:Object; 
     var value:Object; 
     var useIntVal:Boolean; 
     var intVal:int; 
     // for each child node 
     for (property in child.children()) 
     { 
      useIntVal = false; 
      value = property.toString(); 
      if(!(value.substr(1, 2) == '"' AND value.substr(-1, value.length()) == '"')) { 
       useIntVal = true; 
       intVal = parseInt(value); 
      } 
      // button["width"] = 100; 
      if (property.attribute("isStyle") == "true") 
       if(useIntVal) { 
        component.setStyle(property.localName(), intVal); 
       } else { 
        component.setStyle(property.localName(), value); 
       } 
      else { 
       if(useIntVal) { 
        component[property.localName()] = intVal; 
       } else { 
        component[property.localName()] = value; 
       } 
      } 
     } 
    } 
} 

我實現轉換爲int確保我檢查屬性是否應該是一個字符串或一個int。

PS:我現在沒有安裝Flex,因此您可能會發現需要更正的一些錯誤。

在這種情況下,你可能希望有你這樣的XML:

<?xml version="1.0" encoding="UTF-8"?> 
<components type="array"> 
    <component type="mx.controls::ComboBox"> 
     <properties> 
      <width>100</width> 
      <height>100</height> 
      <color isStyle="true">"0xff0000"</location> 
      <label>"Im a Combo Box!"</label> 
     </properties> 
    </component> 
    <component type="mx.controls::Button"> 
     <properties> 
      <width>100</width> 
      <height>100</height> 
      <color isStyle="true">"0xff0000"</location> 
      <label>"Im a Button!"</label> 
     </properties> 
     <children> 
      <!--other children here--> 
     </children> 
    </component> 
</components> 

因爲我懷疑你可以做很多與手風琴一級嵌套。

我會離開實現你的功能。

+0

謝謝......它給了錯誤......讓我工作了它.. – Kevin 2010-02-16 14:55:06

+0

@theband:隨意張貼錯誤。 – 2010-02-16 16:44:51

+0

我們是否可以在Accordian中創建組件......取決於XML – Kevin 2010-02-17 12:43:53