ArrayCollection Objects to String - Проблемы с циклом «для каждого» - PullRequest
0 голосов
/ 03 октября 2009

Это связано с другим вопросом . Но не берите в голову это. Я исправил часть этого.

У меня есть DataGrid, его провайдер данных - ArrayCollection, и я хочу, чтобы он анализировал все itens в нем (тип объекта) в строку.

Для этого я сделал цикл «для каждого», ему удается получить Объект и его значения, но если у меня больше одного объекта, он получает только последний объект, не знаю почему.


Сначала я покажу, как эти элементы добавляются в коллекцию ArrayCollection, так что вы легко поймете все остальное.

В основном приложении у меня есть ArrayCollection:

<mx:ArrayCollection id="collection">

Затем в другом компоненте появляется меню «Добавить элемент», а при добавлении элемента:

private function fazerEncomenda():void
{
    var novoitem:Object;
    novoitem = new Object();
    novoitem.id = "consumivel"+getProdInfo.lastResult.consumivel.id;
    novoitem.tinteiroid = getProdInfo.lastResult.consumivel.id;
    novoitem.label = getProdInfo.lastResult.consumivel.nome;
    novoitem.ref = getProdInfo.lastResult.consumivel.refmarca;
    novoitem.marca = getProdInfo.lastResult.consumivel.marca;
    novoitem.genero = genero.text;
    novoitem.quantidade = quantidade.text;
    Application.application.collection.addItem(novoitem);
}

Затем в другом компоненте DataGrid как его поставщик данных, привязанный к коллекции ArrayCollection

<mx:DataGrid id="compras" x="0" y="0" width="556" dataProvider="{Application.application.collection}" editable="false">
        <mx:columns>
            <mx:DataGridColumn headerText="ID" dataField="tinteiroid" visible="false"/>
            <mx:DataGridColumn headerText="Nome" dataField="label" width="120" />
            <mx:DataGridColumn headerText="Ref" dataField="ref" width="100"/>
            <mx:DataGridColumn headerText="Marca" dataField="marca" width="100"/>
            <mx:DataGridColumn headerText="Género" dataField="genero" width="155"/>
            <mx:DataGridColumn headerText="Quantidade" dataField="quantidade" width="81"/>
        </mx:columns>
    </mx:DataGrid>

А когда нажата кнопка, функция возвращает все объекты и их значения в строку.

И в этой функции он получает только последний элемент в коллекции ArrayCollection.

for each (novoitem in compras.dataProvider)
{
    finish += "TinteiroID:"+novoitem.tinteiroid+"#TinteiroLABEL:"+novoitem.label+"#TinteiroREF:"+novoitem.ref+"#TinteiroMARCA:"+novoitem.marca+"#TinteiroGENERO:"+novoitem.genero+"#TinteiroQUANTIDADE:"+novoitem.quantidade+"#FIMPROD#";
    trace(finish);
}

И, конечно, переменные, используемые в функции:

private var finish:String;
private var novoitem:Object

Как вы видите в готовом варианте, я использовал +=, поэтому он добавляет себя и следующий объект. Вместо этого он добавляет ноль. И только одно нулевое событие, если раньше было 3 элемента.

Не знаю, в чем проблема с этим циклом.

Пожалуйста, помогите. Я схожу с ума здесь.

PS: Извините за плохой английский, это было 3 часа в этом. И никакого прогресса.

РЕДАКТИРОВАТЬ: Добавлена ​​декларация пропущенных переменных

Ответы [ 4 ]

1 голос
/ 04 октября 2009

Более простой способ сделать все это (правда, не с указанными вами метками) - просто использовать встроенный в ActionScript метод ObjectUtil.toString.

Вы бы написали что-то вроде этого:

import mx.utils.ObjectUtil;

public function dumpObj():void {
    myTextField.text = ObjectUtil.toString(obj);
 }

Это должно в значительной степени распечатать каждое свойство каждого имеющегося у вас множественного / вложенного объекта.

ОДНАКО - вы должны внести фундаментальные изменения в свой компонент, если хотите, чтобы он был повторно использован. Вам нужен геттер / сеттер для вашей коллекции. В компонент добавьте этот код:

[Bindable]
private var _myCollection:ArrayCollection;

public function set myCollection (data:ArrayCollection) : void {
    _myCollection = data;
}

public function get myCollection () : ArrayCollection {
    return _myCollection;
}

Есть несколько других способов сделать это - посмотрите, если вам нужно что-то другое. В вашей таблице данных используйте закрытую переменную ArrayCollection, например:

<mx:DataGrid id="compras" x="0" y="0" width="556" dataProvider="{_myCollection}" editable="false">
    <mx:columns>
            <mx:DataGridColumn headerText="ID" dataField="tinteiroid" visible="false"/>
...

В основном приложении вы можете заполнить свой компонент следующим образом:

<kgtm:myComponent x="0" y="20" myCollection="{queryDataAC}"

И вы называете свой ArrayCollection следующим образом:

<mx:ArrayCollection id="queryDataAC">

в коде приложения верхнего уровня вы определяете пространство имен kgtm, чтобы вы могли использовать свой пользовательский компонент, например:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:kgtm="com.kgtm.*"

Затем поместите ваш компонент в папку, соответствующую этому определению пространства имен.

Все это приводит к конечной утилите печати объектов, которую вы определяете для компонента, поскольку это единственная вещь, которая должна знать о том, как распечатывать свои данные.

Определите публичную функцию и заставьте ее распечатать частные данные ArrayCollection, используя ObjectUtil или ваш собственный метод.

public var getLastQueryOutput (): String {

private var output:String = "";
private var len:int = _myCollection.length;
for (var i:int = 0; i <len; i++)   {
    output = output + 
    "TinteiroID:"+_myCollection[i].tinteiroid+
    "#TinteiroLABEL:"+_myCollection[i].label+
    "#TinteiroREF:"+_myCollection[i].ref+
    "#TinteiroMARCA:"+_myCollection[i].marca+
    "#TinteiroGENERO:"+_myCollection[i].genero+
    "#TinteiroQUANTIDADE:"+_myCollection[i].quantidade+
    "#FIMPROD#";

}
trace(output);

}

Надеюсь, это поможет. Если вы называете объект правильно, когда вы помещаете его в ArrayCollection, вы снова можете просто использовать ObjectUtil, как я указывал вверху.

Casp - Проверьте больше моих (и моих коллег) записей в блоге здесь

1 голос
/ 03 октября 2009

Вы пытались использовать обычный цикл for

for (var i:int = 0; i < compras.dataProvider.length; i++) {

novoitem= compras.dataProvider[i];
trace(novoitem); // will output to the console during debugging. 
...
}

в любом случае вы не должны зацикливаться на dataProvider, который вы должны делать на Application.application.collection

1 голос
/ 03 октября 2009

Вы пробовали свойство ".source" вашей коллекции массивов? Я не уверен, что циклы for-each работают с объектами ArrayCollection.

например.,

for each(novoitem in compras.dataProvider.source) { ... }
0 голосов
/ 03 октября 2009

Ребята, я действительно хочу поблагодарить вас.

Благодаря вашим усилиям, Гленн и Эндрю, я сделал это. Еще раз спасибо.

Теперь я опубликую код, чтобы кто-то с подобной проблемой мог получить некоторую помощь.

Здесь приведен код для получения объектов и Itens для каждого объекта в коллекции ArrayCollection.

[Bindable]
private var finish:String = "";
private var novoitem:Object
for (var i:int = 0; i <Application.application.collection.length; i++)
{
 novoitem = compras.dataProvider[i];
 finish = finish + "TinteiroID:"+novoitem.tinteiroid+"#TinteiroLABEL:"+novoitem.label+"#TinteiroREF:"+novoitem.ref+"#TinteiroMARCA:"+novoitem.marca+"#TinteiroGENERO:"+novoitem.genero+"#TinteiroQUANTIDADE:"+novoitem.quantidade+"#FIMPROD#";
 trace(finish);          
}

Еще раз спасибо. Я хотел расставить оба ваших корректора как правильные, но они не полностью. Итак, я объединил оба к этому коду. И вот оно.

Я буду подписывать этот ответ как правильный, но заслуга в этом вся ваша. Я бы не сделал этого, если бы не ваша помощь.

EDIT Это код, который я использовал, однако посмотрите на код, который "CaspNZ", как опубликовано. Это, вероятно, лучший и более легкий подход к производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...