【问题标题】:Flex - Sending a parameter to a custom ItemRenderer?Flex - 将参数发送到自定义 ItemRenderer?
【发布时间】:2010-10-06 10:34:27
【问题描述】:

我想要完成的工作是让我的 Flex Datagrid 中的财务数据进行颜色编码——如果是肯定的,则为绿色;如果是负数,则为红色。如果我想要着色的列是 dataProvider 的一部分,这将是相当简单的。相反,我是根据作为 dataProvider 一部分的另外两列来计算它的。这仍然相当简单,因为我可以在 ItemRenderer 中再次计算它,但计算的另一部分是基于文本框的值。所以,我认为我需要能够将文本框的值发送到自定义 ItemRenderer,但由于该值存储在主 MXML 应用程序中,我不知道如何访问它。将其作为参数发送似乎是最好的方法,但也许还有另一种方法。

这是我的 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 不存在)

那么有谁知道我会怎么做呢?

【问题讨论】:

    标签: apache-flex itemrenderer


    【解决方案1】:

    您可能想从 Flex API 中查看 ClassFactory

    这允许您设置具有任意类型/值的原型对象,每个类型/值都将传递给项目渲染器。来自样本:

    var productRenderer:ClassFactory = new ClassFactory(ProductRenderer);
    productRenderer.properties = { showProductImage: true };
    myList.itemRenderer = productRenderer;
    

    以上代码假设“ProductRenderer”有一个名为“showProductImage”的公共属性,该属性将被设置为“true”。

    【讨论】:

    • 比选择的答案要好得多!添加一个事件处理程序,编写三行代码...完成!
    • 你能举例说明如何做到这一点吗?我有一个列表组件和一个 itemrenderer,我想向 itemrenderer 传递一个额外的值,我该怎么做?
    • 非常优雅,创造奇迹。为了清晰起见,只需要在渲染中定义属性(例如在 fx:Declaration 中)
    【解决方案2】:

    啊,所以我知道outerDocument,但不知道parentDocument。我只能使用 parentDocument。*无论我想从主应用程序中获得什么,只要它是公开的,我就可以访问它。

    例子:

    setStyle("color", (parentDocument.availableFunding >= 0) ? POSITIVE_COLOR : NEGATIVE_COLOR);
    

    甜! :)

    【讨论】:

    • 使用 parentDocument 会将您的项目渲染器耦合到父组件,并使其在您的应用程序的其他任何地方都无法使用。小心行事,这通常被认为是不好的做法。
    【解决方案3】:

    如果需要,您可以使用静态 Application.application 对象直接访问 TextBox 的值,该对象可从应用程序中的任何位置访问。

    例如,如果您希望在 TextInput 控件的值发生更改时通知渲染器,您可以执行类似的操作(在 ItemRenderer 中,其中myTextInput 是在您的主控件中定义的控件的 ID 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>
    

    使用这种方法,当 TextInput 的 text 属性发生变化时,每个 item-renderer 对象都会收到通知,您可以根据当时控件的值采取适当的操作。另请注意,在这种情况下,我已将 useWeakReference 参数设置为 true,以确保侦听器分配不会无意中干扰垃圾收集。希望对您有所帮助!

    【讨论】:

      【解决方案4】:

      还有另一种技术,虽然它最初感觉有点老套,但在实际使用中可能不那么麻烦和清洁。

      它涉及一个鲜为人知的事实,即事件调度当然是同步的,并且事件对象可以被视为由任何事件处理程序填充的值对象。

      即ItemRenderer 可以执行以下操作:

        ...
        var questionEvt:DynamicEvent = new DynamicEvent('answerMeThis', true, true);
        if (dispatchEvent(questionEvt))
        {
            if (questionEvent.answer == "some value")
            ....
      

      在渲染器上方视图层次结构中的某个位置使用相应的处理程序,该处理程序具有事件侦听器并执行以下操作:

      function handleAnswerMeThis(event:DynamicEvent):void
      {
           event.answer = "another value";
           event.dataHelper = new DataHelperThingy();
      }
      

      等等

      它不必是 DynamicEvent - 我只是将它用于懒惰的说明目的。

      【讨论】:

        【解决方案5】:

        我投票支持cliff.meyers' answer

        这是另一个示例,通过构建一个函数来从 MXML 设置 itemRenderer 的属性,该函数将 ClassFactory 包装在 itemRenderer 类周围并注入必要的属性。

        静态函数:

        public static function createRendererWithProperties(renderer:Class,
        properties:Object ):IFactory {
          var factory:ClassFactory = new ClassFactory(renderer); 
          factory.properties = properties;
          return factory;
        }
        

        为列表中的每个项目添加工具提示的简单示例:

        <mx:List dataProvider="{['Foo', 'Bar']}" itemRenderer="{createRendererWithProperties(Label, {toolTip: 'Hello'})}"/>
        

        参考:
        http://cookbooks.adobe.com/post_Setting_the_properties_of_an_itemRenderer_from_MXM-5762.html

        【讨论】:

          【解决方案6】:

          您使用outerDocument 属性。请参阅the fx:Component reference

          【讨论】:

            【解决方案7】:

            您可以在 ItemRenderer 中创建一个“AvailableFunding”静态变量,然后在父文档中设置它。

            public class PriceLabel extends Label {
                public static var availableFunding:int;
                ...
                ...
                SetStyle("color", (PriceLabel.availableFunding >= 0) ? NEGATIVE_COLOR : POSITIVE_COLOR);
            }
            

            在您的父文档中,当您的文本框更新时设置它

            PriceLabel.availableFunding = textBox.text;
            

            显然,每个 ItemRenderer 的值都相同,但看起来这可能就是您正在做的事情。

            【讨论】:

              【解决方案8】:

              我喜欢重写item渲染器的set data函数来改变渲染器当数据提供者改变时如图here

              当您覆盖该函数时,您可以将对象强制转换为您的对象以使 availableFunding 属性可用。

              要访问文本框,您可以尝试创建一个公共属性并将该属性绑定到 mxml 文件中的文本框:

              public var textVar:String;
              
                          <mx:itemRenderer>
                              <mx:Component>
                                  <customrenderer textVar="{txtBox.text}" />
                              </mx:Component>
                          </mx:itemRenderer>
              

              【讨论】:

              • 这行不通。声明的 mx:Component 超出了 txtBox.text 所在的范围。
              【解决方案9】:

              很好的 ClassFactory 示例here

              【讨论】:

              • 给定的链接已损坏。
              【解决方案10】:

              看这个例子:

              itemRenderer="{UIUtils.createRenderer(TextBox,{iconSrc:IconRepository.linechart,headerColor:0xB7D034,subHeaderColor:0xE3007F,textColor:0x75757D})}"
                                                 
              

              【讨论】:

                猜你喜欢
                • 2011-06-05
                • 1970-01-01
                • 2011-04-30
                • 2012-04-18
                • 2011-05-14
                • 2011-01-16
                • 1970-01-01
                • 2011-01-26
                • 1970-01-01
                相关资源
                最近更新 更多