【问题标题】:How do I tell a DataProvider to update?如何告诉 DataProvider 更新?
【发布时间】:2009-08-15 01:35:07
【问题描述】:

我正在使用一个数组来填充一个 DataProvider,我正在使用它来填充一个列表组件。像这样:

var myDataProvider = new DataProvider(this.myArray);
this['list'].dataProvider = myDataProvider;

当对数组进行更改时,我想告诉 DataProvider 进行更新,以便这些更改将反映在列表组件中。如果有一种方法可以告诉 DataProvider 侦听数组中的更改并更新自身,那就太好了,但我会选择一种手动更新它的方法。

我可以将 DataProvider 替换为新的 DataProvider,但随后列表失去了选择。我想我可以通过 DataProvider 并比较和修改每个条目以使其与数组匹配,但这似乎太麻烦了。有没有办法告诉 DataProvider 更新以匹配数组?

编辑:我正在寻找一种在 Flash 而不是 Flex 中执行此操作的方法。

【问题讨论】:

    标签: flash actionscript-3 dataprovider


    【解决方案1】:

    数组在 AS 3 中不可绑定;他们自己不会调度/触发数据绑定事件。

    如果您正在使用 Flex,您可以将数组包装在一个 可绑定的 ArrayCollection 中,并操作 ArrayCollection 而不是 Array,一切都会自动运行希望。

    所以,在实践中:

    var myAC:ArrayCollection = new ArrayCollection(myArray);
    var myDP = new DataProvider(myAC);
    
    myAC[0] = 'changing the array!'; // will be reflected in the dataProvider
    

    更好的是,如果您将 DataProvider 实例传递给 Flex 组件,您通常(几乎总是)可以直接传递 ArrayCollection。但是,您没有提供足够的上下文让我确定这一点。

    这里有一些有用的链接:

    编辑:我的错,我确实假设您在上面使用了 Flex。

    在普通的旧 AS3 中,主体是相同的。 Array 不调度事件,但 DataProvider 可以。如果您可以对 dataProvider 本身进行更改,那么您就可以开始了。

    AS3 DataProvider 类提供了一系列数据操作方法,例如 addItemremoveItemreplaceItemreplaceItemAt

    所以,它基本上归结为您需要对源数组进行什么样的更改。通常情况下,您可以通过DataProvider 进行操作。

    【讨论】:

    • 谢谢,但我很确定 ArrayCollection 是一个 Flex 类。有没有办法在 Flash 中获得此功能?
    • 感谢您的编辑。我考虑过这一点,但源数组是在不同的类中创建的,它只是将它用作数组。重写它以使用 DataProvider 似乎有点笨拙。有没有办法只告诉 DataProvider 重新配置自己以匹配更改的数组?
    • 由于对象是通过引用传递的,因此DataProvider和创建Array的类可以各自根据需要使用该数组,而无需相互了解。应该不需要修改其他类。
    • @Tyler:但是...... DataProvider 不能/不知道对数组的更改。当然,它有一个对它的引用,但它不知道它发生了变化,因为 Array 不会调度更改事件。
    【解决方案2】:

    在过去的 4 个小时里,我一直在试图弄清楚数据提供者和原始数组之间的联系是什么。我发现在数据网格上使用 GetItemAt 方法也会更新数据网格的数据提供者在使用 GetItemAt 方法时自动更新的数组。

    import fl.events.ListEvent;
    import fl.data.DataProvider;
    
    var arr = new Array();
    arr.push ({Name:"Mike",Height:"6'4"});
    arr.push ({Name:"Jackie",Height:"5'9"});
    arr.push ({Name:"Mike",Height:"0'10"});
    
    dg.addColumn("Name");
    dg.addColumn("Height");
    dg.dataProvider = new DataProvider(arr);
    dg.addEventListener(ListEvent.ITEM_CLICK,updatename);
    
    function updatename(e):void {
    e.target.getItemAt(e.rowIndex)["Name"] = name_txt.text;
    trace (arr[e.rowIndex]["Name"]);
    }
    

    让我烦恼的是我使用 removeItemAt 方法,它从数据网格中删除行,但不更新数组。在这个项目开始时,我不知道 getItemAt 会更新数组,所以我花了 4 个小时试图弄清楚我的代码是如何减去两次的。

    【讨论】:

      【解决方案3】:

      同理,如果更新数组,它会自动更新数据网格(至少在 Flash CS4 中是这样)。

      import fl.events.ListEvent;
      import fl.data.DataProvider;
      
      var arr = new Array();
      arr.push ({Name:"Mike",Height:"6'4"});
      arr.push ({Name:"Jackie",Height:"5'9"});
      arr.push ({Name:"Mike",Height:"0'10"});
      
      dg.addColumn("Name");
      dg.addColumn("Height");
      dg.dataProvider = new DataProvider(arr);
      dg.addEventListener(ListEvent.ITEM_CLICK,updatename);
      
      
      function updatename(e):void {
          arr[e.rowIndex]["Name"] = "none";
      }
      

      但是,您仍然无法使用 arr.splice 删除数组中的一行并让它自动更新数据网格。对于删除(拼接)和添加(推送),您必须分别更新数组和数据网格。

      【讨论】:

        【解决方案4】:

        您可以更改数据,然后重新分配数据提供者

        var myDataProvider = new DataProvider(this.myArray);
        this['list'].dataProvider = myDataProvider;
        
        myDataProvider.getItemAt(0)["Name"] = "Some change";
        this['list'].dataProvider = myDataProvider;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-14
          • 2014-10-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多