完整Flex程序+详细解释之便条管理系统(Tree/回溯/XML/Event) Annotated Flex Sample Application: Note Management...

本文介绍了一个使用Flex开发的小程序,旨在管理个人备忘录。程序具备增删改查等功能,并利用Tree和Datagrid组件展示目录与备忘内容。数据存储于SharedObject中,支持XML格式的读写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

四, 08/21/2008 - 22:24 — Ligl
演示+代码
一 目标及要求:

设计一个小程序,用以记录备忘等小东西,需要有一个目录,一个按照目录分门别类的显示目录下的Notes.同时应具有,CRUD[Create,Read,Update,Delete]目录与Note的功能,Tree的dataprovider不能为XML,应使用ITreeDataDescriptor.所有数据存放于SharedObject中.

二 设计:

1.XML大概格式:
<cat label="SimpleNoteManagement"> 
   <cat label="Cat1">
        <note title="Notetitle0" date="Tue Aug 12 2008 12:00:00 AM" detail="Note0detail"/>
        <cat labe="Cat1.1>
             <note title="Notetitle1" date="Tue Aug 12 2008 12:00:00 AM" detail="Note1detail"/>
             <note title="Notetitle2" date="Tue Aug 12 2008 12:00:00 AM" detail="Note2detail"/>
        </cat>
    </cat>
    <cat label="Cat2"/>
</cat>
2.上述XML将存储与SharedObject中.
3.类设计:
Category:
        public static var root : Category;
        public var label : String;
        public var subCats : ArrayCollection;
        public var notes : ArrayCollection;
        public var parent : Category;
        public function addSubCat(item:Category):void 
        public function addNote(note:Note):void
        public function delCat(item:Category):void
        public function delNote(note:Note):void
        public function catToXml():XML
        public function toXML():XML
Note:
        public var title :String;
        public var date : String;
        public var detail :String;
        public var parent:Category;
        public function noteToXml():XML
4.系统初始化时,读取XML,并将之转换为Category对象.通过Category中subCats与notes,分别为Tree及datagrid提供数据.
5.设计操作过程;Cat与Note的CRUD.
6.操作结束后,将Category转换为XML,存储与SharedObejct.

三 详细设计:

1.程序初始化及读取XML转换为Catefory对象:

        /**
         * 初始化函数.首先调用loadXML()函数以获取SharObject中的XML数据.
         * 然后通过readCat将XML数据读取为对象,并将最顶级的Root对象返回给root.
         * root为Category类的static变量.
         */
        public  function onComplete():void {
              cats = loadXML();
            Category.root = readCat(cats);   
            trace(Category.root.label);   
            setButton();   
          }

loadXML函数:

public function loadXML():XML{
    var NoteManagementShareObject:SharedObject = SharedObject.getLocal("NoteManagementShareObjectSave");
    trace((NoteManagementShareObject.data.catandnote as XML).toXMLString());
    return NoteManagementShareObject.data.catandnote;
}

readCat函数:

          /**
           * 遍历XML,首先判断xml.localName是否为cat,如果是,则说明此xml为我们要求的含有目录信息的xml,可以通过下面代码进行解析,如果不是则返回错误.
           * 回溯:首先,因为已经确定xml.localName是"cat",因此新建一个Category,并赋值.
           * 然后判断他的孩子,在他的孩子中遍历:
           * 如果localName是cat的,为目录,运行readCat,创建一个category,如果发现孩子还有孩子,并且还有cat,则继续执行,直到最最底层,然后将最后一个
           * category[subcat]的parent设置为newcat,并把category[subcat]添加到newcat的subCats中,以此执行,直到完成整个回溯过程.
           * 如果localName是note,则直接新建note,赋值,加入到newcat.notes中.
           */

至此,初始化完成,并取得具有牵头作用的root.

2.Tree实现:

<mx:Tree dataDescriptor="{new CategoryTreeDataDiscriptor()}" x="40" y="90" labelField="lebal"
    dataProvider="{Category.root}" width="228" height="484" 
    showRoot="false" click="categoryClickHand();" id="treeCategory" ></mx:Tree>

CategoryTreeDataDiscriptor函数:

public class CategoryTreeDataDiscriptor implements ITreeDataDescriptor
{

    /**
     * 取得node的children,也就是node的subCats,故使用node as  category来调用subCats
     */
    public function getChildren(node:Object, model:Object=null):ICollectionView
    {
        return (node as Category).subCats;
    }
    /**
     * 判断node是否有孩子.
     * subCats有可能不为空,但没有内容,因此,如果为空或没有内容,则应返回false
     * 注意If语句的条件.如果互换位置,则将报错,因为If将先执行or的第一部分,如果互换,遇到空则报错.
     */
    public function hasChildren(node:Object, model:Object=null):Boolean
    {
        var hasC:Boolean = true;
        if ((node as Category).subCats == null || (node as Category).subCats.length < 1) {
            hasC = false
        }
        return hasC;
    }
    /**
     * 判断是否为分支
     * 应直接使用hasChildren返回值,便于后期的管理与修改.
     */
    public function isBranch(node:Object, model:Object=null):Boolean
    {
        return hasChildren(node,model);
    }
    public function getData(node:Object, model:Object=null):Object
    {
        return node;
    }
    public function addChildAt(parent:Object, newChild:Object, index:int, model:Object=null):Boolean
    {
        throw Error("Not Supported");
    }
    public function removeChildAt(parent:Object, child:Object, index:int, model:Object=null):Boolean
    {
        throw Error("Not Supported");
    }
}

3.datagrid实现:

步骤2中的Click函数:

          /**
           * 响应Tree的状态.在点击Tree的时候,设定右侧用于显示Note的datagrid的dataprovider.
           *
           */
             private function categoryClickHand():String {
                 var rowNumber:String;
            if (treeCategory.selectedItem == null){
                buttonDelCat.enabled = false;
                buttonEditCat.enabled = false;
            }
              else if ((treeCategory.selectedItem as Category).notes != null){
                  //noteUI.datagridNotes.dataProvider=(treeCategory.selectedItem as Category).notes;
                  dataGridNoteList.dataProvider=(treeCategory.selectedItem as Category).notes;   
                  rowNumber =  String((treeCategory.selectedItem as Category).notes.getItemIndex((treeCategory.selectedItem as Category).notes) + 1);
                  trace(rowNumber);
              }
              return rowNumber;
          }

至此,初步实现对XML的读取与实现.

4.对象转换为XML,并存储

/**
* 保存XML.
* 定义变量:NoteManagementShareObject类型为SharedObject,赋值.
* 通过toXML函数,通过root对象的subcats将所有cat对象读取出为XML.
* 并将该XML写入到SharedObject中.
*/          
public function save(givenParentXML:XML = null):void{
    var NoteManagementShareObject:SharedObject = SharedObject.getLocal("NoteManagementShareObjectSave");
    Category.root.toXML();
    trace(Category.root.toXML().toXMLString());
    givenParentXML.appendChild(Category.root.toXML());
    NoteManagementShareObject.data.catandnote = Category.root.toXML();
    NoteManagementShareObject.flush();
}

toXML函数:

/**
* 通过回溯,将对象转换为XML
*/
public function toXML():XML {
    var parentXML : XML = <cat label={label}></cat>;
    var noteCounter:int;
    var catCounter:int;           
    //添加note       
    //if (notes != null && notes.length>0) {
        for(noteCounter = 0; notes != null && notes.length>0&&noteCounter < notes.length; noteCounter++){
            parentXML.appendChild((notes[noteCounter] as Note).noteToXml());
        }
    //}           
    //如果含有分支,则将分支进行writeToXml;
    //if (subCats != null && subCats.length>0) {
        for(catCounter = 0; subCats != null && subCats.length>0&&catCounter < subCats.length ; catCounter++) {
            parentXML.appendChild((subCats[catCounter] as Category).toXML());               
        }
    //}            
    return parentXML;
}

至此,程序的读取与保存工作已完成.下面是中间操作:

5.以Note举例,列举其CRUD步骤

5.1 Create:

          /**
           * Note增加函数,新建一个note对象,调用Category中的addNote函数.该函数将新建的Note对象追加到相对应的cat的notes arraycollection中.         
           */
           public function addNewNote():void {        
              var noteTobeAdded:Note = new Note();
             noteTobeAdded.title = inputTitle.text;
             noteTobeAdded.date = inputDate.selectedDate.toLocaleString();
             noteTobeAdded.detail = inputDetail.text;
             noteTobeAdded.parent = treeCategory.selectedItem as Category;
            (treeCategory.selectedItem as Category).addNote(noteTobeAdded);  
          }

public function addNote(note:Note):void{
    if(notes == null) {
        notes = new ArrayCollection();
    }
    notes.addItem(note);
}

5.2 Read:

列表将通过datagrid实现,前面通过tree的点击响应函数categoryClickHand()已经实现.每个Note的显示类似于Update部分.

5.3 Update:

          /**
           * Note编辑函数,新定义一个EditWindow[专门用来编辑Note的TitleWindow],定Title,定义要传递的对象,注册对编辑结束事件的监听.
           * 在点击之后弹出该窗口
           */
          public function editTheNote():void{
                  //定义一个对话框
                var noteEditer:EditWindow = EditWindow(PopUpManager.createPopUp(this,EditWindow,true));   
                noteEditer.title="NoteUpdate";
                noteEditer.note = dataGridNoteList.selectedItem as Note;
                noteEditer.addEventListener(EventEditComplete.EVENTEDITCOMPLETE,onEditComplete);
                PopUpManager.centerPopUp(noteEditer);
          }

弹出窗口内的函数:

public function set note(n:Note):void{
    _note = n;

    inputTitle.text = _note.title;
    inputDate.selectedDate = new Date(_note.date);
    inputDetail.text = _note.detail;
    trace("Update set is called");
    trace(_note.title);
}
public function get note():Note{
    return _note;
}

public function upDateTheNoteAndDispatch():void{
    _note.title = inputTitle.text;
    _note.date = String(inputDate.selectedDate);
    _note.detail = inputDetail.text;
    var e:EventEditComplete;
    e = new EventEditComplete();
    dispatchEvent(e);
    PopUpManager.removePopUp(this);
}

5.4 Delete:

          //Note删除函数,使用note的parent,调用delNote函数.
          public function delTheNote():void {
              (dataGridNoteList.selectedItem as Note).parent.delNote(dataGridNoteList.selectedItem as Note);
            treeCategory.invalidateList();   
          }

delNote函数:

public function delNote(note:Note):void {
    note.parent.notes.removeItemAt(note.parent.notes.getItemIndex(note));
}

四:测试及抓图:

测试 略

111112008-8-21 22-00-58

 111112008-8-21 21-59-00 111111008-8-21 21-58-41

五:出现问题及解决方法:

1.读取或写入XML函数出错:应先在纸上画出执行过程,仔细分析后设计或修改函数

2.Tree的ITreeDataDescriptor不会使用:应对照API及相关帮助文档进行设计.

六:相关知识点总结

1.Tree ITreeDataDescriptor

2.SharedObject

3.Event

七:其他

设定在tree或datagrid无选定时部分按钮,如编辑,删除等无效的方法:

1. 将相关按钮enable设置为flash.

2. 在程序初始化时,call一个函数:setButton();    setButton可以相应tree或datagrid的点选,以设定按钮状态

3.setButton函数:

public function setButton():void{
    dataGridNoteList.addEventListener(ListEvent.CHANGE,setNoteButtonState);
    treeCategory.addEventListener(ListEvent.CHANGE,setButtonCatState);

}

4.响应函数:以Note举例;

public function setNoteButtonState(event:ListEvent):void{
    if (dataGridNoteList.selectedItem != null){
        buttonEditNote.enabled = true;
        buttonDelNote.enabled = true;
        buttonViewDetail.enabled = true;
    } else {
        buttonEditNote.enabled = false;
        buttonDelNote.enabled = false;
        buttonViewDetail.enabled = false;
    }
}

组件本身enable为false,当selected的时候变为true,功能已经实现了,为什么还要加else呢?

因为选定之后,按ctrl+鼠标单击,selected的状态已经改变,但是button仍然可用,因为此时并没有任何响应该状态的函数.加入else之后,可以解决这个问题.

回應

一, 08/25/2008 - 13:10 — Ligl

... some code here ...

  1. public function loadXML():XML{    
  2.     var NoteManagementShareObject:SharedObject = SharedObject.getLocal("NoteManagementShareObjectSave");    
  3.     trace((NoteManagementShareObject.data.catandnote as XML).toXMLString());    
  4.     return NoteManagementShareObject.data.catandnote;    
  5. }  
public function loadXML():XML{       var NoteManagementShareObject:SharedObject = SharedObject.getLocal("NoteManagementShareObjectSave");       trace((NoteManagementShareObject.data.catandnote as XML).toXMLString());       return NoteManagementShareObject.data.catandnote;   }  
  1. public function loadXML():XML{    
  2.     var NoteManagementShareObject:SharedObject = SharedObject.getLocal("NoteManagementShareObjectSave");    
  3.     trace((NoteManagementShareObject.data.catandnote as XML).toXMLString());    
  4.     return NoteManagementShareObject.data.catandnote;    
  5. }   
  6.   
  7. <PRE class=js name="code"><A onmouseover="alert('对不起,图片不能随便下载!')" href="javascript:void(0)" jQuery1221017308187="25"><IMG height=50 src="j2.gif" width=99 align=center border=0></A>  
  8. </PRE>  
  9. 转自:http://riashanghai.com/node/27
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游鱼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值