【问题标题】:How to get a view to read data如何获取读取数据的视图
【发布时间】:2011-12-06 20:53:59
【问题描述】:

我需要在我的职业中转换很多东西 - 所以我正在为我的手机构建一个转换工具,其中包含一些我经常使用的转换。

现在,我希望能够正确构建它。到目前为止,这是我的代码:

    <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" title="Length">

<fx:Script>
    <![CDATA[
        protected function button1_clickHandler(event:MouseEvent):void
        {
            var Result:String;
            var Finish:Number;
            var Start:Number = parseFloat(Input.text);
            Finish = Start * convert.selectedItem.data; 
            Result = String(Finish);
            answer.text = Result;

        }
    ]]>
</fx:Script>

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>




<s:TextInput id="Input" x="20" y="46"/>
<s:SpinnerListContainer x="140" y="122" width="200" height="200">
    <s:SpinnerList id="convert" height="100%" width="100%" labelField="label" selectedIndex="1">
        <s:ArrayList>
            <fx:Object label="km to mi" data="0.62137119224"></fx:Object>
            <fx:Object label="km to yd" data="1093.6132983 "></fx:Object>
            <fx:Object label="km to ft" data="3280.839895"></fx:Object>
            <fx:Object label="km to in" data="39370.07874"></fx:Object>
            <fx:Object label="km to m" data="1000"></fx:Object>
            <fx:Object label="km to cm" data="100000"></fx:Object>
            <fx:Object label="km to mm" data="1000000"></fx:Object>

    </s:ArrayList>
            </s:SpinnerList>
        </s:SpinnerListContainer>
        <s:Label id="answer" x="66" y="533" width="348" text="Answer"/>
        <s:Button x="66" y="377" width="338"           click="button1_clickHandler(event)" label="Button"/>

    </View>

如你所见,我会遇到一些问题:

1) 一切都是硬编码的,如果我想添加、删除或更改数组中的元素,那就有点麻烦了。

2) 我的体积和重量转换的观点基本相同。遇到同样的问题。

我想做的,但我在理解上遇到了一些麻烦,就是将所有硬编码的东西放在一个地方,并根据我以前的视图显示相同的视图,这只是一个简单的、很难的视图-编码列表。

我正在考虑类似 xml 表的东西,并向对象添加 category = "length"category = "weight" 元素,以便我可以在列表中显示来自 xml 的类别,然后当我单击“长度”时它从此列表中读取标签+数据。这是一个好的解决方案吗?以及如何让selectedItem 记住应该从哪个部分填充视图?

拥有多个xml文件会更好吗?但这仍然意味着我必须在需要时更新一大堆地方。

基本上,我需要以下帮助:

所以 - 现在问题有两个:

1) 如何在多个视图中保持与 xml/db 的连接打开?

2) 如何根据数据库中的信息填充端视图?

感谢您的建议和帮助。

【问题讨论】:

    标签: apache-flex flex-mobile


    【解决方案1】:

    大约一个月前,我刚刚完成了一个应用程序,它使用了我认为最“灵活”的解决方案。 (呵呵呵呵)

    (第一个答案:) 如果您熟悉/熟悉(良好的)数据库设计,您可以设计一个 SQLite 数据库,允许您添加和修改您正在使用的所有数据。

    (如果没有,我建议: http://www.amazon.com/The-Art-SQL-Stephane-Faroult/dp/0596008945/ref=sr_1_14?s=books&ie=UTF8&qid=1336262973&sr=1-14

    http://www.amazon.com/SQL-Demystified-Andrew-Oppel/dp/0072262249/ref=sr_1_1?s=books&ie=UTF8&qid=1336263052&sr=1-1

    ...这篇文章需要的时间比我预期的要长!嘿嘿嘿;P =D)

    基本上是这样的: 类别表(例如体积、长度等)和另一个用于特定名称/值对的表(“km 到 mi”= 0.62137119224 [每个在单独的列中])以及类别 id 列。

    然后在您的主页上,您的 init() 为类别表创建一个 DAO(数据访问对象 [如果您还不知道,请研究一下]),然后将类别提取到 ArrayCollection 并将其设置为 dataProvider在您的类别列表中(在主视图上 - 或任何地方)。

    (第二个答案:) 让类别列表的更改处理程序获取 selectedItem 并将其作为 navigator.pushView() 中的第二个参数传递。这会将 VO(值对象——如果您不知道,则另作研究)作为“数据”属性发送到新视图。

    在“推送视图”中,使用您的 creationComplete 处理程序来“捕获”(使用)数据变量,该变量将包含类别的名称和 ID。为 values 表创建一个新的 DAO,然后使用 data.id 值加载具有该类别 ID 的所有值。然后将新的 ArrayCollection 设置为值列表的 dataProvider。

    然后创建另一个视图以选择要以相同方式编辑的值。除了该“流程”中的最终视图将是一个包含类别、名称和值(带有保存和取消按钮)输入的表单,该表单也将填充适当的数据。 (注意:使用类别 DAO 来获取类别的名称,以便在更改类别时可以使用类别名称和 ID。

    ...那么只需在该视图上实现插入和更新方法以及每个 DAO 中所需的 SQL 和方法即可。

    您可以使用 Lita (http://www.dehats.com/drupal/?q=node/58) 构建、设计和预填充您的数据库。

    ...我可能会带回一些不错的示例代码/文件(如果我记得的话)

    我为那些正在阅读的人做了一些例子,希望我能...

    //////////////////////////////////////  
    //VO (Value Object)  
    //Category.as  
    //////////////////////////////////////  
    
    
    package dao  
    {  
    
    [Bindable]//Makes all public properties bindable
    public class Category
    {   
    
        import mx.collections.ArrayCollection;
    
        public var id:int = -1;
        public var categoryName:String;
        private var categoryDao:CategoryDAO;
    
        public function Category() {}
    
    
    
        public function get exists():Boolean {
            return this.id > -1;
        }
    
    
        //"Super" convenient methods
        //Not really part of Value Objects / Value Object Pattern
        //May actually be a bad practice if you have many VO instances,
        //you have the potential for a DAO instance in each
        //when only one instance could be used.
    
        public function insert():void {
            if( !categoryDao ){ categoryDao = new CategoryDAO;}
            categoryDao.insert( this );
        }
    
        public function update():void {
            if( !categoryDao ){ categoryDao = new CategoryDAO;}
            categoryDao.update( this );
        }
    
        public function deleteRow():void {
            if( !categoryDao ){ categoryDao = new CategoryDAO;}
            categoryDao.deleteRow( this );
        }
    }
    }
    
    
    //////////////////////////////////////  
    //DAO (Data Access Object)  
    //CatagoryDAO.as    
    //////////////////////////////////////  
    
    
    package dao
    {
    import flash.data.SQLConnection;
    import flash.data.SQLStatement;
    import flash.filesystem.File;
    
    import mx.collections.ArrayCollection;
    
    public class CategoryDAO
    {
        public static var _sqlConnection:SQLConnection;
        public var failed:Boolean;
        public var errorMessage:*;
    
        public function CategoryDAO() {
        }
    
        public function getAll():ArrayCollection
        {
            var sql:String = "SELECT * FROM categories"                     
            + " ORDER BY categoryName ASC";
            var stmt:SQLStatement = new SQLStatement();
            stmt.sqlConnection = sqlConnection;
            stmt.text = sql;
            stmt.execute();
            var result:Array = stmt.getResult().data;
            if( result ){
                var list:ArrayCollection = new ArrayCollection();
                for (var i:int=0; i < result.length; i++){
                    list.addItem( buildVO( result[i] ) );   
                }
                return list;
            } else {
                return null;
            }
        }
    
        public function getByCategoryId(id:int):Category
        {
            var sql:String = "SELECT * FROM categories WHERE id=?";
            var stmt:SQLStatement = new SQLStatement();
            stmt.sqlConnection = sqlConnection;
            stmt.text = sql;
            stmt.parameters[0] = id;
            stmt.execute();
            var result:Array = stmt.getResult().data;
            if( result && result.length == 1 ){
                return buildVO( result[0] );
            } else {
                return null;
            }
        }
    
        public function insert(category:Category):void
        {
            var sql:String = 
                "INSERT INTO categories ( categoryName )" + 
                " VALUES ( :name )";
            var stmt:SQLStatement = new SQLStatement();
            stmt.sqlConnection = sqlConnection;
            stmt.text = sql;
            stmt.parameters[":name"] = category.categoryName;
            this.execute( stmt );
        }
    
        public function update(category:Category):void
        {
            var sql:String = 
                "UPDATE categories" +
                " SET categoryName = :name" +
                " WHERE id = :id";
            var stmt:SQLStatement = new SQLStatement();
            stmt.sqlConnection = sqlConnection;
            stmt.text = sql;
            stmt.parameters[":name"] = category.categoryName;
            stmt.parameters[":id"] = category.id;
            this.execute( stmt );
        }
    
        public function deleteRow(category:Category):void {
            var sql:String = 
                "DELETE FROM categories" +
                " WHERE id = :id";
            var stmt:SQLStatement = new SQLStatement();
            stmt.sqlConnection = sqlConnection;
            stmt.text = sql;
            stmt.parameters[":id"] = category.id;
            this.execute( stmt );
        }
    
        protected function execute(stmt:SQLStatement):void {
            try {
                stmt.execute();
            } catch(error:Error) {
                this.failed = true;
                this.errorMessage = error.message;
            } 
        }
    
        protected function buildVO(o:Object):Category
        {
            var category:Category = new Category();
            category.id = o.id;
            category.categoryName = o.categoryName;
            return category;
        }
    
    
        public function get sqlConnection():SQLConnection
        {
            if (_sqlConnection) return _sqlConnection;
            var file:File = 
                   File.documentsDirectory.resolvePath(DbUtility.DB_FILE_NAME);
            var fileExists:Boolean = file.exists;
            _sqlConnection = new SQLConnection();
            _sqlConnection.open(file);
            return _sqlConnection;
        }
    }
    }
    
    
    
    //////////////////////////////////////  
    //CategoryView.mxml  
    //////////////////////////////////////  
    
    <?xml version="1.0" encoding="utf-8"?>
    <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:dao="dao.*"
        opaqueBackground="#111111"
        title="All Categorys"
        creationComplete="init()">
    <fx:Script>
        <![CDATA[
            import dao.DbUtility;
            import dao.DropPoint;
            import dao.Category;
            import dao.CategoryDAO;
    
            protected var dbVerifyUtil:DbUtility
    
            protected function init():void
            {
                dbVerifyUtil = new DbUtility;
                dbVerifyUtil.confirmDb();
    
                if( dbVerifyUtil.dbExists() ){
                    var categorysDAO:CategoryDAO = new CategoryDAO;
                    categoryList.dataProvider = categorysDAO.getAll();
                }
    
            }
    
            protected function categorySelected():void
            {
                navigator.pushView( CategoryListView, 
                        categoryList.selectedItem );
            }
    
            protected function newCategory():void
            {
                navigator.pushView( EditCategoryView );
            }
    
            protected function viewCategory():void
            {
                navigator.pushView( CategoryListView, 
                        categoryList.selectedItem );
            }
    
        ]]>
    </fx:Script>
    
    
    <s:List id="categoryList"
            left="10" right="10" top="10" bottom="85"
            change="viewCategory()"
            dataProvider="{data}"
            itemRenderer="irs.CategoryIR">
    </s:List>
    
    
    <s:Button label="Add Category"
              left="104" bottom="10" height="43"
              click="newCategory()"/>
    <s:Label text="Touch a category to view or edit it."
             y="326" horizontalCenter="0"/>
    </s:View>
    
    
    //////////////////////////////////////  
    //CategoryListView.mxml  
    //////////////////////////////////////  
    
    <?xml version="1.0" encoding="utf-8"?>
    <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:dao="dao.*"
        creationComplete="init()">
    
    <fx:Script>
        <![CDATA[
            import dao.Value;//Value VO
            import dao.Category;//Category VO
    
            import mx.collections.ArrayCollection;
    
            import spark.events.IndexChangeEvent;
    
            private var category:Category;
    
            protected function init():void
            {
                var category:Category = data as Category;
                listValues.dataProvider =
                        valueDAO.getByCategoryId(
                                category.id );
            }
    
            protected function editValue():void
            {
                navigator.pushView( EditValueView,
                        listValues.selectedItem );
            }
    
            protected function editCategory():void
            {
                navigator.pushView( EditCategoryView, category );
            }
    
        ]]>
    </fx:Script>
    
    <s:viewMenuItems>
        <s:ViewMenuItem label="Edit Category"
                        click="editCategory()"
                        icon="@Embed('assets/edit.png')"/>
        <s:ViewMenuItem label="Add Location"
                        click="addLocation()"
                        icon="@Embed('assets/plus.png')"/>
    </s:viewMenuItems>
    
    <s:List id="listValues"
            left="10" right="10" top="10" bottom="60"
            labelFunction="labelValue"
            change="editValue()"
            itemRenderer="irs.ValueIR">
    </s:List>
    </s:View>
    

    【讨论】:

    • ...heheheheehe 我没注意到你的用户名! =P
    • 那是一个很好的答案,感谢您的提示、建议、代码和幽默!
    • 没有汗水!缺少一些细节,但我认为它们很容易弄清楚。希望它有所帮助。 =)
    【解决方案2】:

    您是否考虑过使用资源包?还是 LSO?

    在持久化 Flex 数据时,您有 4 个主要选项。

    1. 关系数据库(这里似乎有点矫枉过正)
    2. XML(您似乎已经习惯了)
    3. Resource Bundles
    4. Local Shared Objects

    上面链接的 LSO 示例 (#4) 为您的问题提供了一个潜在的解决方案:

    ...我如何让 selectedItem 记住应该从 xml 列表的哪个部分填充视图?

    sn-p:

    public function initApp():void {
        mySO = SharedObject.getLocal("mydata");
        if (mySO.data.visitDate==null) {
           welcomeMessage = "Hello first-timer!"
        } else {
           welcomeMessage = "Welcome back. You last visited on " +
              getVisitDate();
        }
     }
    
    private function getVisitDate():Date {
       return mySO.data.visitDate;
    }
    
    private function storeDate():void {
       mySO.data.visitDate = new Date();
       mySO.flush();
    }
    
    private function deleteLSO():void {
       // Deletes the SharedObject from the client machine.
       // Next time they log in, they will be a 'first-timer'.
       mySO.clear();
    }
    

    我建议使用 XML 和 LSO 或资源包和 LSO 的组合——您的 XML/RB 存储不变的静态数据,而您的 LSO 跟踪动态数据(查看设置等)。

    【讨论】:

      【解决方案3】:

      数据检索

      据我了解您的问题,您不必保持连接打开。

      1. 从数据库中检索数据
      2. 解析并存储检索到的 理想情况下,集合中的数据是 ArrayCollection(您不想 处理基于 XML 的对象,它们在操作 String 时很好 值,但它们会立即成为 .as 中的痛苦 执行类型转换和高级添加和删除操作)

      通用转换

      然后,使用下面示例中的绑定,当您将一个值从一个单位转换为另一个时,您所要做的就是进行两次转换:

      1. 转换为定义的单位(理想情况下是 SI 单位,如我的 示例)
      2. 从 SI 单位转换为所需单位。

      示例

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application 
          xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" 
          minWidth="400" minHeight="300">
          <s:layout>
              <s:VerticalLayout/>
          </s:layout>
          <fx:Script>
              <![CDATA[
      
                  import mx.collections.ArrayCollection;
      
                  [Bindable]
                  private var unitz:ArrayCollection = new ArrayCollection([
                      {
                          label:"Length",
                          units: new ArrayCollection([
                              {label: "meter", toSI: 1},
                              {label: "kilometer", toSI: 1000},
                              {label: "inch", toSI: 0.0254}
                          ])
                      },
                      {
                          label:"Temperature",
                          units: new ArrayCollection([
                              {label: "kelvin", toSI: 1},
                              {label: "celsius", toSI: 274.15},
                              {label: "farenheit", toSI: 255.927778}
                          ])
                      }
                  ]);
      
                  private function resetFields():void
                  {
                      fromValue.text = "";
                      toValue.text = "";
                  }
      
                  private function onInputChange():void
                  {
                      var fu:Object = fromUnitCB.selectedItem;
                      var tu:Object = toUnitCB.selectedItem;
      
                      toValue.text = (Number(fromValue.text)*fu.toSI/tu.toSI).toString();
                  }
      
              ]]>
          </fx:Script>
      
          <s:HGroup width="100%" height="40">
              <s:ComboBox
                  id="categoryCB"
                  dataProvider="{unitz}"
                  change="resetFields()"
              />
              <s:ComboBox id="fromUnitCB" dataProvider="{categoryCB.selectedItem.units}"/>
              <s:ComboBox id="toUnitCB" dataProvider="{categoryCB.selectedItem.units}"/>
          </s:HGroup>
          <s:HGroup width="100%">
              <s:TextInput id="fromValue" change="onInputChange()"/>
              <s:Label id="toValue"/>
          </s:HGroup>
      </s:Application>
      

      【讨论】:

      • 谢谢 - 这是在移动设备上,使用视图,不能使用 ComboBox。而且我试图避免将任何转换数据直接硬编码到视图中。
      • 嗯,我很确定 SpinnerList 使用 IList 数据提供者,所以您可以轻松地调整我的示例,不是吗?
      猜你喜欢
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 2016-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多