简体   繁体   English

如何获取视图以读取数据

[英]How to get a view to read data

I need to convert a lot of stuff in my profession - so I'm building a conversion tool for my phone with some of the conversions I use a lot. 我需要转换专业中的很多东西-所以我正在为手机构建一个转换工具,其中包含一些我经常使用的转换。

Now, I want to be able to build this properly. 现在,我希望能够正确构建它。 So far, here's my code: 到目前为止,这是我的代码:

    <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>

As you can see, I'm going to run into some problems with this: 如您所见,我将遇到一些问题:

1) Everything is hard-coded, and if I want to add, remove or change the elements in the array, it's going to be a bit of a pain. 1)一切都是硬编码的,如果我想添加,删除或更改数组中的元素,那会有些痛苦。

2) I have a view that is essentially the same for my volume and weight conversions. 2)对于体积和重量换算,我的看法基本相同。 With the same problem. 同样的问题。

What I'd like to do, but I'm having some trouble understanding, is getting all that hard-coded stuff in one place and having the same view show it based on my previous view which is just a plain, hard-coded list. 我想做的是,但我有一些理解上的困难,是将所有硬编码的内容放在一个位置,并根据我以前的视图(只是一个简单的硬编码列表)以相同的视图显示它。

I'm thinking of something like an xml sheet, and adding a category = "length" or category = "weight" element to the objects, so that I can show the category from the xml in the List, then when I click "length" it reads the label + data from this list. 我正在考虑类似xml表的内容,并在对象中添加category = "length"category = "weight"元素,以便可以从列表中的xml中显示该类别,然后单击“ length” ”,它将从此列表中读取标签+数据。 Is that a good solution? 那是一个好的解决方案吗? And how exactly do I get the selectedItem to remember which part of the xml list the view should be populated from? 以及如何准确地使selectedItem记住应该从中填充视图的xml列表的哪一部分?

Would it be better to have several xml files? 拥有几个xml文件会更好吗? But that still would mean I have to update a whole bunch of places when I need it. 但这仍然意味着我必须在需要时更新很多地方。

Basically, I need assistance with: 基本上,我需要以下方面的帮助:

So - Now the question is two-fold: 所以-现在的问题有两个:

1) How to keep a connection to xml/db open across multiple views? 1)如何在多个视图之间保持与xml / db的连接打开?

2) How to populate the end-view from information from the db? 2)如何从数据库中的信息填充最终视图?

Thanks for the advice and help. 感谢您的建议和帮助。

I just finished an app about a month ago that's uses what I think would be the most "Flex"ible solution. 我大约一个月前刚刚完成了一个应用程序,该应用程序使用了我认为是最“灵活”的解决方案。 (hehehehe) (呵呵呵呵)

(First Answer:) If you're into/familiar with (good) database design, you could design a SQLite db that allows you to add to & modify all the data you're working with. (第一个答案:)如果您熟悉/熟悉(良好的)数据库设计,则可以设计一个SQLite数据库,该数据库允许您添加和修改正在使用的所有数据。

(If not, I'd recommend either: 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/The-Art-SQL-Stephane-Faroult/dp/0596008945/ref=sr_1_14? s=books&ie= UTF8& qid=1336262973&sr= 1-14

or 要么

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

...this post is going to take longer than I anticipated! ...此职位所需的时间比我预期的要长! hehehhehee ;P =D ) hehehhehee; P = D)

Basically what it'd be is: Tables for categories (eg Volume, Length, etc.) and another for specific name/value pairs ("km to mi" = 0.62137119224 [each in separate columns]) with a category id column to. 基本上是这样的:具有类别ID列的类别(例如体积,长度等)表和特定名称/值对(“ km至mi” = 0.62137119224 [每个在单独的列中])的表。

Then on your home page you have your init() create an DAO (Data Access Object [research if you don't know already]) for the categories table, then fetch the categories into an ArrayCollection and set it as the dataProvider on your category list (on the home view -- or wherever). 然后在首页上,您的init()为类别表创建一个DAO(数据访问对象[如果您还不知道,则进行搜索]),然后将类别提取到ArrayCollection中并将其设置为类别中的dataProvider列表(在主视图上或其他位置)。

(Second Answer:) Have your change handler for the category list grab the selectedItem and pass it as the second param in navigator.pushView(). (第二个答案:)让类别列表的更改处理程序抓住selectedItem并将其作为第二个参数传递给navigator.pushView()。 That will send the VO (Value Object -- another to research if you don't know it) to the new View as the "data" property. 这会将VO(值对象-如果您不知道,则另外进行研究)作为“数据”属性发送到新的视图。

In the "pushed view," use your creationComplete handler to "catch" (use) the data variable, which will contain the category's name and id. 在“推送视图”中,使用creationComplete处理程序“捕获”(使用)数据变量,该变量将包含类别的名称和ID。 Create a new DAO for the values table and then use the data.id value to load all your values with that category id. 为值表创建一个新的DAO,然后使用data.id值加载具有该类别ID的所有值。 Then set your new ArrayCollection as the dataProvider of your value list. 然后将新的ArrayCollection设置为值列表的dataProvider。

Then create another View for choosing values to edit in the same way. 然后创建另一个视图以选择要以相同方式编辑的值。 Except the final view in that "flow" would be a form with inputs for category, name, & value (with save & cancel buttons) that would get populated with the appropriate data too. 除了该“流”中的最终视图之外,表单将是一个包含类别,名称和值(带有保存和取消按钮)的输入的表单,该表单也将填充适当的数据。 (Note: use a category DAO to get the names of the categories so that the category names & ids are available if you change a category. (注意:使用类别DAO可以获取类别的名称,以便在更改类别时可以使用类别名称和ID。

...Then it's just a matter of implementing insert & update methods on that View and the SQL & methods needed in each DAO. ...然后只需在该View上实现插入和更新方法以及每个DAO中所需的SQL和方法即可。

You can use Lita ( http://www.dehats.com/drupal/?q=node/58 ) build, design, pre-populate your database. 您可以使用Lita( http://www.dehats.com/drupal/?q=node/58 )构建,设计并预填充数据库。

...I may come back with some nice example code/files (if I remember) ...我可能会带一些不错的示例代码/文件(如果我记得的话)

I made some examples for those who were reading and hoped I would... 我为那些正在阅读的人举了一些例子,希望我能...

//////////////////////////////////////  
//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>

Data retrieve 资料检索

As I understand your problem, you don't have to keep a connection open. 据我了解您的问题,您不必保持连接打开状态。

  1. Retrieve the data from your database 从数据库中检索数据
  2. Parse and store the retrieved data in a collection ideally an ArrayCollection (you don't want to handle XML based objects, they're fine when manipulating String values, but they instantly become a pain in the .as when you want to perform type-conversion and advanced add and remove operations) 将检索到的数据解析并存储在一个理想的ArrayCollection集合中(您不想处理基于XML的对象,在处理String值时它们很好,但是当您要执行type-时,它们立即成为。转换和高级添加和删除操作)

Generic conversion 通用转换

Then, with binding as in the following sample, all you have to do is always have two conversions when you convert a value from an unit to another : 然后,使用下面的示例中的绑定,当您将一个值从一个单位转换为另一个单位时,您所要做的就是始终进行两次转换:

  1. conversion into a defined unit (ideally the SI unit, as in my example) 转换为定义的单位(如我的示例,最好是SI单位)
  2. conversion from the SI unit to the desired unit. 从SI单位转换为所需单位。

Sample 样品

<?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>

Have you looked at using resource bundles? 您是否考虑过使用资源包? Or LSOs? 还是LSO?

When persisting Flex data, you have 4 main options. 保留Flex数据时,有4个主要选项。

  1. Relational Databases (seems like overkill here) 关系数据库(似乎在这里过分杀伤)
  2. XML (which you already seem comfortable with) XML(您似乎已经很满意)
  3. Resource Bundles 资源包
  4. Local Shared Objects 本地共享对象

The LSO example, linked above (#4), gives a potential solution to your question: 上面的链接(#4)的LSO示例为您的问题提供了一种可能的解决方案:

... how exactly do I get the selectedItem to remember which part of the xml list the view should be populated from? ...如何准确地使selectedItem记住应该从中填充视图的xml列表的哪一部分?

snippet: 片段:

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();
}

I'd recommend using either a combination of XML and LSOs or resource bundles and LSOs--where your XML/RB stores non-changing, static data and your LSO keeps track of dynamic data (view settings, etc). 我建议使用XML和LSO或资源包和LSO的组合-您的XML / RB存储不变的静态数据,而LSO跟踪动态数据(视图设置等)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM