调用flex组件时调用设置函数的顺序

时间:2010-04-14 02:18:00

标签: flex

我有一个名为TableDataViewer的组件,它包含以下数据及其相关的集合函数:

        [Bindable]
        private var _dataSetLoader:DataSetLoader;
        public function get dataSetLoader():DataSetLoader {return _dataSetLoader;}
        public function set dataSetLoader(dataSetLoader:DataSetLoader):void {
            trace("setting dSL"); 
            _dataSetLoader = dataSetLoader;
        }

        [Bindable]
        private var _table:Table = null;
        public function set table(table:Table):void {
            trace("setting table");
            _table = table;
            _dataSetLoader.load(_table.definition.id, "viewData", _table.definition.id);
        }

此组件嵌套在另一个组件中,如下所示:

<ve:TableDataViewer width="100%" height="100%" paddingTop="10" dataSetLoader="{_openTable.dataSetLoader}"
    table="{_openTable.table}"/>

查看日志中的跟踪,在调用set dataSetLoader之前调用set table。这是一个真正的耻辱,因为set table()需要设置dataSetLoader才能调用它的load()函数。

所以我的问题是,有没有办法在声明组件时强制执行对set函数调用的命令?

1 个答案:

答案 0 :(得分:0)

Flex文档提到(在某处,我暂时找不到)MXML中设置的属性初始化顺序未定义。也就是说,有时dataSetLoader可能首先设置其值,然后设置table,或者有时相反。{/ p>

要解决此问题,您可以使用invalidateProperties() and invalidateDisplayList()等Flex失效方法等待所有属性都设置完毕,然后立即执行处理。

例如,以下是您处理问题的方法 请注意,当我们知道我们同时拥有_dataSetLoader.load(...)commitProperties()值时,我们会将table方法的调用移至dataSetLoader方法:

    [Bindable]
    private var _dataSetLoader:DataSetLoader;
    private var dataSetLoaderChanged:Boolean = false;
    public function get dataSetLoader():DataSetLoader {return _dataSetLoader;}
    public function set dataSetLoader(dataSetLoader:DataSetLoader):void{
        trace("setting dSL"); 
        _dataSetLoader = dataSetLoader;

        dataSetLoaderChanged = true;
        invalidateProperties();
    }

    [Bindable]
    private var _table:Table = null;
    private var tableChanged:Boolean = false;
    public function set table(table:Table):void {
        trace("setting table");
        _table = table;

        tableChanged = true;
        invalidateProperties();
    }

    override protected function commitProperties():void
    {
        super.commitProperties();

        if (tableChanged || dataSetLoaderChanged)
        {
            if (_dataSetLoader != null)
            {
                _dataSetLoader.load(_table.definition.id, "viewData", _table.definition.id);
            }

            tableChanged = false;
            dataSetLoaderChanged = false;
        }
    }