`
smithfox
  • 浏览: 55416 次
  • 性别: Icon_minigender_1
  • 来自: hf
社区版块
存档分类
最新评论

[译] Flex Collection 事件和手动通知变化

阅读更多

 

[说明: 本文为 http://www.smithfox.com/?e=38 原创, 转载请注明原文, 谢谢]

英文原文: http://livedocs.adobe.com/flex/3/html/help.html?content=about_dataproviders_5.html

原创翻译: http://www.smithfox.com/?e=38

(JavaEye的文章编辑器怎么不能自动换行呢? 大家看的累就直接到我的个人blog看  )

学习Flex中最常见的例子可能就是放一个DataGrid控件,然后放个HttpService之类和后台交互的组件,绑定一个ArrayCollection。

这个例子让我们养成了一个非常不好的习惯(最起码我看到的新手Flex程序都是这样): 每次都是根据后台数据构造生成新一个ArrayCollection对象,再赋给DataGrid控件的dataProvider,使整个DataGrid都刷新.

原因就是对Collection怎么和DataGrid进行交互根本不了解。看完这篇文章相信菜鸟能变成火鸟. (哈哈,还是鸟)

Collection事件和手动变化通知

集合用下面事件来表示发生了变化. 我们可以用这些事件来监控集合的变化从而作相应的显示上的更新.
Collection事件: CollectionEvent, PropertyChangeEvent和FlexEvent.

  1. 当今集合发生变化时, 发布 CollectionEvevnt.COLLECTION_CHANGE.
  2. CollectionEvent.kind(CollectionEventKind类型)用来表示是什么变化类型,比如UPDATE.
  3. CollectionEvent.items(是一个Array类型), 如果是ADD和REMOVE kind 事件, 这个数组包含了被删除或是被增加的items.   对于UPDATE事件, items则是一个事件数组,数组成员全都是PropertyChangeEvent, 每个事件表示相应的item的update
  4. PropertyChangeEvent.kind(类型是PropertyChangeEventKind)表示是那个属性发生了变化.
  5. 当游标位置发生了变化, 视图游标(View cursor)发布一个事件.   type属性是FlexEvent.CURSOR_UPDATE

 

例如,一个自定义控件用一个collection作为它的data provider, 你肯定想每次collection发生变化时控件能被自动更新以显示修改后的最新数据. 这时上面这些集合事件就能派上用场.

假设我们做一个汽车租赁的预定系统. 应用程序就能用COLLECTION_CHANGE 事件来监听 预定信息.为这个事件的侦听器函数起个名字叫 reservationsChanged,这个函数判断 Change事件的kind 字段做不同业务逻辑.

  • 如果kind是ADD,    遍历事件的items属性,调用一个函数更新预定信息的显示(一个显示所有预定时间的框)
  • 如果kind是REMOVE, 遍历事件的items属性, 调用一个函数将这些预定信息从框中删除
  • 如果kind是UPDATE, 遍历事件的items属性, 此时每个item是一个PropertyChangeEvent事件, 我们调用函数更新所有对应的预定信息的显示.
  • 如果kind是RESET,  调用一个函数重置预定信息.

代码如下:

 

private function reservationsChanged(event:CollectionEvent):void {
    switch (event.kind) {
        case CollectionEventKind.ADD:
            for (var i:uint = 0; i < event.items.length; i++) {
                    updateReservationBox(Reservation(event.items[i]));
            }
            break;

        case CollectionEventKind.REMOVE:
            for (var i:uint = 0; i < event.items.length; i++) {
                removeReservationBox(Reservation(event.items[i]));
            }
            break;

        case CollectionEventKind.UPDATE:
            for (var i:uint = 0; i < event.items.length; i++) {
                if (event.items[i] is PropertyChangeEvent) {
                    if (PropertyChangeEvent(event.items[i]) != null) {
                         updateReservationBox(Reservation(PropertyChangeEvent(
                            event.items[i]).source));
                    }
                }
                else if (event.items[i] is Reservation) {
                    updateReservationBox(Reservation(event.items[i]));
                }
        }
        break;

        case CollectionEventKind.RESET:
            refreshReservations();
            break;
    }
}

 

大家知道,没有实现IEventDispatcher接口的数据项是不可监控的,而且Flash和Flex对象和其它的基本数据类型都没有实现这个接口.

因此当你修改了Array或是一DisplayObject对象的属性时,你就必须调用itemUpdated()方法来手动更新集合视图, 

这个方法将 已被修改的item对象 和 修改之前的item对象 一并作为参数.

当你必须用Array来直接作为控件的dataProvider时, 你也可以用itemUpdated()方法来手动通知collection发生了变化。

Array直接作dataProvider时, 控件会将数据封装到一个collection对象, 但是这个collection封装对象在Array数据发生改变时是不知道的,

所以必须用itemUpdated()手动通知。

注: 当你直接在一个collection中增加或删除子项时,或是通过ICollectionView, IList的方法来修改colletion时, 你完全没有必须调用itemUpdated().

大家知道,当一个类,或是一个对象的声明上加[Bindable]时,需要类(或是对象的类)实现了IEventDispatcher接口。

因为只有实现了IEventDispatcher接口才能发布事件(propertyChange事件).

当你在类的声明之上加[Bindable]时,这个类的任何属性在发生变化时,都会发布propertyChange事件;

如果你仅是在指定属性之上加[Bindable]标记时,那只有加了[Bindable] meta tag的这些属性才会发布propertyChange事件。

collection会侦听propertyChange事件.假设你有一个myCollection,这个collection的item的类有一个[Bindable] myVariable的变量,那么 myCollection.getItemAt(0).myVariable="myText" 将会触发一个propertyChange事件(假定是没有必要使用itemUpdated()的情况).

所以最常见的itemUpdate用法是: 一个不能Bindable的类,或是无法实现IEventDispatcher接口的类的数据(属性)发生变化时来用通知collection.

下面的例子展示在这样的情景时你就可以用itemUpdated()

假设你有一个你不能控制和再编辑的类:

public class ClassICantEdit {    public var field1:String;    public var field2:String;}

你还有一个ArrayCollection, 里面的item全都是 classICantEdit对象.

public var myCollection:ArrayCollection = new ArrayCollection();

你有如下一个DataGrid控件:

<mx:DataGrid dataProvider="{myCollection}"/>

当你象下面更改myCollection中的item的值时, DataGrid控件是不会自动更新的:

myCollection.getItemAt(0).field1="someOtherValue";

为更新DataGrid控件,你必须 itemUpdated()函数:

myCollection.itemUpdated(collectionOfThoseClasses.getItemAt(0));


禁止和启用自动更新

Collection还提供了enableAutoUpdate()和disableAutoUpdate()方法,这两个方法可以启用或是禁止数据发生变化时自动更新数据视图的功能。

collection的 disableAutoUpdate()方法会阻止基本数据改变事件被collection视图广播.同时还阻止,collection自身作为一个结果集被改变的事件.
当一个collection绑定为一个控件的dataProvider时, 用这个方法可以防止因collection多次变化而引起控件不必要的中间显示更新。
例如, DataGrid控件在item被选中时,就会调用disableAutoUpdate(), 当这个item不再被选中时再调用enableAutoUpdate(),

这样可以当你正在编辑一个item时,不会因为这item是在一个排序的collection中而导致在屏幕上下乱跳.
下面的代码片断显示了怎样调用disableAutoUpdate(), enableAutoUpdate()

var obj:myObject = myCollection.getItemAt(0);
myCollection.disableAutoUpdate();
obj.prop1 = 'foo';
obj.prop2 = 'bar';
myCollection.enableAutoUpdate();


例子: 在DataGrid控件中修改数据

下面的例子你可以在DataGrid控件中增加, 删除, 修改数据

 

<?xml version="1.0"?>
<!-- dpcontrols\ModifyDataGridData.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="500"
    height="600" >
 
    <mx:Script>
        <![CDATA[
            import mx.events.*;
            import mx.collections.*;
    
            // Add event information to a log (displayed in the TextArea).
            public function collectionEventHandler(event:CollectionEvent):void {
                switch(event.kind) {
                    case CollectionEventKind.ADD:
                        addLog("Item "+ event.location + " added");
                        break;
                    case CollectionEventKind.REMOVE:
                        addLog("Item "+ event.location + " removed");
                        break;
                    case CollectionEventKind.REPLACE:
                        addLog("Item "+ event.location + " Replaced");
                        break;
                    case CollectionEventKind.UPDATE:
                        addLog("Item updated");
                        break;
                }
            }
            // Helper function for adding information to the log.
            public function addLog(str:String):void {
                log.text += str + "\n";
            }
    
            // Add a person to the ArrayCollection.
            public function addPerson():void {
                ac.addItem({first:firstInput.text, last:lastInput.text,
                    email:emailInput.text});
                    clearInputs();
            }
    
            // Remove a person from the ArrayCollection.
            public function removePerson():void {
                // Make sure an item is selected.
                if (dg.selectedIndex >= 0) {
                    ac.removeItemAt(dg.selectedIndex);
            }
        }
    
        // Update an existing person in the ArrayCollection.
        public function updatePerson():void {
            // Make sure an item is selected.
            if (dg.selectedItem !== null) {
                ac.setItemAt({first:firstInput.text, last:lastInput.text,
                    email:emailInput.text}, dg.selectedIndex);
            }
        }
    
        // The change event listener for the DataGrid.
        // Clears the text input controls and updates them with the contents
        // of the selected item.
        public function dgChangeHandler():void {
            clearInputs();
            firstInput.text = dg.selectedItem.first;
            lastInput.text = dg.selectedItem.last;
            emailInput.text = dg.selectedItem.email;
        }
    
        // Clear the text from the input controls.
        public function clearInputs():void {
            firstInput.text = "";
            lastInput.text = "";
            emailInput.text = "";
        }
 
        // The labelFunction for the ComboBox;
        // Puts first and last names in the ComboBox.
        public function myLabelFunc(item:Object):String {
            return item.first + " " + item.last;
        }
        ]]>
    </mx:Script>
    
    <!-- The ArrayCollection used by the DataGrid and ComboBox. -->
    <mx:ArrayCollection id="ac"
            collectionChange="collectionEventHandler(event)">
        <mx:source>
            <mx:Object first="Matt" last="Matthews" email="matt@myco.com"/>
            <mx:Object first="Sue" last="Sanderson" email="sue@myco.com"/>
            <mx:Object first="Harry" last="Harrison" email="harry@myco.com"/>
        </mx:source>
    </mx:ArrayCollection>
 
    <mx:DataGrid width="450" id="dg" dataProvider="{ac}"
            change="dgChangeHandler()">
        <mx:columns>
            <mx:DataGridColumn dataField="first" headerText="First Name"/>
            <mx:DataGridColumn dataField="last" headerText="Last Name"/>
            <mx:DataGridColumn dataField="email" headerText="Email"/> 
        </mx:columns>
    </mx:DataGrid>
 
    <!-- The ComboBox and DataGrid controls share an ArrayCollection as their
        data provider.
        The ComboBox control uses the labelFunction property to construct the
        labels from the dataProvider fields. -->
    <mx:ComboBox id="cb" dataProvider="{ac}" labelFunction="myLabelFunc"/>
    
    <!-- Form for data to add or change in the ArrayCollection. -->
    <mx:Form>
       <mx:FormItem label="First Name">
            <mx:TextInput id="firstInput"/>
       </mx:FormItem>
       <mx:FormItem label="Last Name">
            <mx:TextInput id="lastInput"/>
       </mx:FormItem>
       <mx:FormItem label="Email">
            <mx:TextInput id="emailInput"/>
       </mx:FormItem>
    </mx:Form>
    
    <mx:HBox>
        <!-- Buttons to initiate operations on the collection. -->
        <mx:Button label="Add New" click="addPerson()"/>
        <mx:Button label="Update Selected" click="updatePerson()"/>
        <mx:Button label="Remove Selected" click="removePerson()"/>
        <!-- Clear the text input fields. -->
        <mx:Button label="Clear" click="clearInputs()"/>
    </mx:HBox>
    
    <!-- The application displays event information here -->
    <mx:Label text="Log"/>
    <mx:TextArea id="log" width="100" height="100%"/>
</mx:Application>

 

 

Flash显示效果请到 http://livedocs.adobe.com/flex/3/html/help.html?content=about_dataproviders_5.html 文章最后部分查看.

[说明: 本文为 http://www.smithfox.com/?e=38 原创, 转载请注明原文, 谢谢]

 

 

分享到:
评论

相关推荐

    Flex事件机制详细说明

    Flex支持两种类型的事件:系统内置的事件和用户自定义事件。内置事件由Flex框架提供,用于处理常见的交互场景;自定义事件则允许开发者根据具体需求创建特定类型的事件来扩展Flex的应用能力。 在Flex中,事件模型...

    flex事件flex事件flex事件flex事件

    在前端开发领域,Flex布局...综上所述,虽然"flex事件"的具体含义未明,但我们可以看到Flex布局与JavaScript事件的结合可以实现丰富的交互和动态布局。为了更深入理解实际场景中的"flex事件",需要更多的上下文信息。

    flex控件事件

    对于列表和数据网格等控件,滚动事件(ScrollEvent.SCROLL)允许我们对用户滚动行为作出反应,而数据改变事件(DataEvent.COLLECTION_CHANGE)则在数据源发生变化时触发,可用于实时更新UI。 通过深入了解和应用...

    flex自定义事件、简单例子说明

    在Flex应用中,事件是一种对象,表示应用程序或用户界面中的某些行为或状态变化。默认情况下,Flex提供了许多内置事件类型,如`MouseEvent.CLICK`等,但有时我们可能需要创建自己的事件类型来更好地满足特定需求。...

    flex事件运行流程

    总之,理解Flex事件运行流程,特别是`applicationComplete`和`creationComplete`事件,对于编写高效、响应式的Flex应用至关重要。在实践中,熟练掌握这些事件可以帮助开发者更好地控制组件的创建、初始化和显示时机...

    Flex4.5事件机制

    在Flex中,用户的行为,如点击按钮或输入文本,会触发相应的事件,这些事件包含关于事件的信息,并通知相关对象进行处理。 DOM3事件机制包括四个主要部分:注册事件侦听器、发送事件、侦听事件和移除事件侦听器。以...

    flex的事件详解

    事件在Flex应用开发中占据了核心地位,它们不仅确保了用户界面的响应能力,还使开发者能够通过用户输入和系统状态变化来控制程序逻辑。 #### 二、事件的概念与重要性 **事件**是ActionScript 3.0和Flex开发的基础...

    flex4自定义事件用法

    通常,我们会选择`flash.events.Event`或`mx.events.FlexEvent`作为基类,前者适用于基本事件,后者则为Flex框架提供了一些额外的属性和方法。 - 自定义事件类应包含一个构造函数,用于初始化事件的属性。例如,...

    Flex 布局变化时的动画效果解析 简单版

    总之,Flex布局动画主要依赖于CSS的`transition`和`animation`属性,它们能帮助我们在Flex元素变化时创建流畅的过渡效果。通过实践和调试,开发者可以创造出各种各样的动态Flex布局,提升网站的视觉吸引力和用户体验...

    flex 关于事件的例子

    Flex中有多种内置事件类型,如`MouseEvent`(鼠标事件)、`KeyboardEvent`(键盘事件)、`FocusEvent`(焦点事件)和`UIComponentEvent`(UI组件事件)等。例如,`click`事件在用户点击按钮时触发,`change`事件在...

    flex 事件 代码生成器

    在Flex应用开发中,处理各种用户交互和事件响应是不可或缺的一部分,而手动编写这些事件处理代码往往耗时且易出错。 此代码生成器能够帮助开发者自动创建与UI组件相关的事件监听器和处理函数。例如,当需要为按钮...

    Flex的事件机制笔记

    Flex事件机制是Adobe Flex应用程序开发中的核心组成部分,它允许组件之间进行有效的通信和交互。对于初级Flex程序员或爱好者来说,理解这一机制至关重要。在本文中,我们将深入探讨Flex事件的各个方面,包括事件流、...

    Flex 4的十大变化

    Flex 4,也被称为Gumbo,是Adobe Flex框架的一个重大更新,它引入了许多关键变化以提升RIA(Rich Internet Applications)的开发效率和用户体验。以下是Flex 4中的十大变化的详细说明: 1. **Adobe Catalyst集成**...

    Flex 事件机制,flex入门学习

    总的来说,Flex 的事件机制是其灵活性和可扩展性的重要组成部分。理解和掌握这一机制,有助于开发者更好地设计和构建富互联网应用程序,提高用户体验,并有效地处理用户交互。通过深入了解事件注册、分发、监听以及...

    关于flex事件的讲解

    很多新人对Flex的事件机制都不太熟悉,在使用过程中难免会出现各种问题,这是一个非常普遍的问题,为了更快更好的帮助大家,将介绍一下Flex中事件的各种机制和用法。 Flex的精髓之一就是事件和绑定机制,了解之后,...

    Flex事件解析以及Flex基础功能介绍

    事件是Flex中实现用户交互的关键,涵盖了从用户操作(如点击、键盘输入)到数据变化(如数据绑定更新)的各个方面。理解并掌握Flex事件,是实现复杂界面逻辑的前提。 1. **事件类型**:Flex定义了一系列事件类型,...

    Flex各自定义组件事件通讯例子

    在Flex开发中,自定义组件和事件通讯是构建复杂应用程序的关键技术。本示例通过一个简单的用户登录场景,深入解析了如何实现组件间的有效通信。下面将详细解释Flex自定义组件、事件处理以及它们在实际应用中的作用。...

    flex事件机制的demo

    Flex ActionScript3.0事件机制的Demo, 举例说明了事件的三个阶段,事件的派发,事件的侦听,事件的拦截,自定义事件等相关知识点. 以上知识点在Demo中都有体现,初学者请仔细分析代码,加强理解,多调试、修改、验证以加深...

    Flex自定义组件和事件

    在Flex中,自定义组件和事件的使用对于创建功能丰富的用户界面至关重要。下面我们将详细探讨这两个主题。 ### 一、Flex自定义组件 #### 1. 创建自定义组件的原因 在Flex应用中,有时标准组件库提供的组件无法满足...

Global site tag (gtag.js) - Google Analytics