从XML创建Flex组件

问题描述:

我有一个XML,它有一个属性选项或组合框,解析我需要动态地在我的flex中创建组件。从XML创建Flex组件

Viatropos给予了美好的代码,但我不能够执行它...任何人都可以生产它...感谢

+1

你需要问一个问题... – Simon 2010-02-04 10:07:49

+0

我想创建一个阅读XML的组件 – Kevin 2010-02-04 10:31:43

您可以创建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

这里是@ 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