Flex: ¿envío de un parámetro a un ItemRenderer personalizado?
(10)
Lo que intento lograr para obtener datos financieros en mi Flex Datagrid con código de color, verde si es positivo; rojo si es negativo. Esto sería bastante sencillo si la columna que quiero coloreada fuera parte del dataProvider. En cambio, lo estoy calculando en base a otras dos columnas que forman parte del proveedor de datos. Eso todavía sería bastante sencillo porque podría simplemente calcularlo de nuevo en el ItemRenderer, pero otra parte del cálculo se basa en el valor de un cuadro de texto. Entonces, lo que creo que debo poder hacer es enviar el valor de la caja de texto al ItemRenderer personalizado, pero como ese valor está almacenado en la aplicación MXML principal, no sé cómo acceder a él. Enviarlo como un parámetro parece ser la mejor manera, pero tal vez haya otro.
Aquí está el código actual para mi ItemRenderer:
package {
import mx.controls.Label;
import mx.controls.listClasses.*;
public class PriceLabel extends Label {
private const POSITIVE_COLOR:uint = 0x458B00 // Green
private const NEGATIVE_COLOR:uint = 0xFF0000; // Red
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
/* Set the font color based on the item price. */
setStyle("color", (data.AvailableFunding >= 0) ? NEGATIVE_COLOR : POSITIVE_COLOR);
}
}
(data.AvailableFunding no existe)
Entonces, ¿alguien sabe cómo iba a lograr esto?
Ah, entonces sabía sobre outerDocument pero no parentDocument. Solo pude usar parentDocument. * Lo que quiera de la aplicación principal y puedo acceder a él siempre que sea público.
Ejemplo:
setStyle("color", (parentDocument.availableFunding >= 0) ? POSITIVE_COLOR : NEGATIVE_COLOR);
¡Dulce! :)
Ejemplo agradable de ClassFactory here
Es posible que desee examinar ClassFactory desde las API Flex:
Esto le permite establecer un prototipo de objeto con tipos / valores arbitrarios, cada uno de los cuales pasará al renderizador de elementos. De la muestra:
var productRenderer:ClassFactory = new ClassFactory(ProductRenderer);
productRenderer.properties = { showProductImage: true };
myList.itemRenderer = productRenderer;
El código anterior supone que "ProductRenderer" tiene una propiedad pública llamada "showProductImage" que se establecerá con un valor de "verdadero".
Hay otra técnica que, aunque inicialmente parece un poco hacky, es quizás menos engorrosa y más limpia en el uso real.
Implica el hecho poco observado de que un envío de eventos es, por supuesto, síncrono y el objeto de evento puede tratarse como un objeto de valor poblado por cualquier controlador de eventos.
es decir, el ItemRenderer puede hacer algo como:
...
var questionEvt:DynamicEvent = new DynamicEvent(''answerMeThis'', true, true);
if (dispatchEvent(questionEvt))
{
if (questionEvent.answer == "some value")
....
Con un controlador correspondiente en algún lugar de la jerarquía de vista encima del representador que tiene un detector en el evento y hace algo como:
function handleAnswerMeThis(event:DynamicEvent):void
{
event.answer = "another value";
event.dataHelper = new DataHelperThingy();
}
etc.
No necesita ser un DynamicEvent: solo lo uso para fines ilustrativos.
Me gusta sobrescribir la función de configuración de datos del renderizador de elementos para cambiar el renderizador cuando el proveedor de datos cambia como se muestra here
Cuando anula la función, puede lanzar el objeto a su objeto para que la propiedad de disponibilidad disponible esté disponible.
Para acceder al cuadro de texto, puede intentar crear una propiedad pública y vincular la propiedad al cuadro de texto en el archivo mxml:
public var textVar:String;
<mx:itemRenderer>
<mx:Component>
<customrenderer textVar="{txtBox.text}" />
</mx:Component>
</mx:itemRenderer>
Mira este ejemplo:
itemRenderer = "{UIUtils.createRenderer (TextBox, {iconSrc: IconRepository.linechart, headerColor: 0xB7D034, subHeaderColor: 0xE3007F, textColor: 0x75757D})}"
Puede acceder al valor de TextBox directamente, si es necesario, mediante el uso del objeto static Application.application
, al que se puede acceder desde cualquier lugar de la aplicación.
Por ejemplo, si desea que se notifique a los procesadores cuando cambie el valor del control TextInput, puede hacer algo como esto (desde dentro de su ItemRenderer, y donde myTextInput
es el ID del control definido en su clase principal de MXML):
<mx:Script>
<![CDATA[
import mx.core.Application;
private function creationCompleteHandler(event:Event):void
{
Application.application.myTextInput.addEventListener(TextEvent.TEXT_INPUT, handleTextInput, false, 0, true);
}
private function handleTextInput(event:TextEvent):void
{
if (event.currentTarget.text == "some special value")
{
// Take some action...
}
}
]]>
</mx:Script>
Con este enfoque, cada objeto item-renderer será notificado cuando la propiedad de texto de TextInput cambie, y usted puede tomar las medidas apropiadas basadas en el valor del control en ese momento. Observe también que establecí el argumento useWeakReference
como verdadero en este caso, para asegurarme de que las asignaciones del oyente no interfieran involuntariamente con la recolección de basura. ¡Espero eso ayude!
Puede crear una variable estática ''AvailableFunding'' en el ItemRenderer y luego configurarla en el documento principal.
public class PriceLabel extends Label {
public static var availableFunding:int;
...
...
SetStyle("color", (PriceLabel.availableFunding >= 0) ? NEGATIVE_COLOR : POSITIVE_COLOR);
}
En su documento principal, configúrelo cuando su cuadro de texto se actualice
PriceLabel.availableFunding = textBox.text;
Obviamente, será el mismo valor para cada ItemRenderer pero parece que eso podría ser lo que estás haciendo de todos modos.
Voto por la respuesta de cliff.meyers .
Aquí hay otro ejemplo sobre cómo establecer las propiedades de un itemRenderer de MXML mediante la construcción de una función que envuelve un ClassFactory alrededor de la clase itemRenderer y que inyecta las propiedades necesarias.
La función estática:
public static function createRendererWithProperties(renderer:Class,
properties:Object ):IFactory {
var factory:ClassFactory = new ClassFactory(renderer);
factory.properties = properties;
return factory;
}
Un ejemplo simple que agrega una información sobre herramientas a cada elemento en una lista:
<mx:List dataProvider="{[''Foo'', ''Bar'']}" itemRenderer="{createRendererWithProperties(Label, {toolTip: ''Hello''})}"/>
Referencia:
http://cookbooks.adobe.com/post_Setting_the_properties_of_an_itemRenderer_from_MXM-5762.html
outerDocument
propiedad outerDocument
. Por favor, consulte el fx:Component
referencia del fx:Component
.