Flex DropdownList CreationComplete错误

时间:2010-09-08 16:01:03

标签: flex drop-down-menu

我有一个显示提供商列表的DropdownList&必须选择与该患者相关的提供者。

下拉列表:

<s:DropDownList id="providerList"
        width="80%"
        fontSize="12"
        fontWeight="bold"
        selectionColor="white"
        creationComplete="providerList_creationCompleteHandler(event)"
        dataProvider="{model.practiceProviderList.practiceProviders}"/>

其中practiceProviders是一个ArrayCollection

CreationCompleteHandler函数:

protected function providerList_creationCompleteHandler(event:FlexEvent):void
   {
    var firstN:String;
    var lastN:String;
    var providerObj:Provider = new Provider();

    if (model.patientDetails.patientDetail.patientProviders != null && model.patientDetails.patientDetail.patientProviders.length > 0)
    {
     firstN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.firstName;
     lastN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.lastName; 

for (var count:int = 0; count < patientDetailsModel.practiceProviderList.practiceProviders.length; ++count)
     {
 providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;

if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
      {
 this.providerList.selectedIndex = count;
      }
     }
    }
   }

问题是当我第一次访问此页面时,错误是:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
 at com.newwavetechnologies.modules::demographics/providerList_creationCompleteHandler()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:166]
 at com.newwavetechnologies.modules::demographics/__providerList_creationComplete()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:359]
 at flash.events::EventDispatcher/dispatchEventFunction()
 at flash.events::EventDispatcher/dispatchEvent()
 at mx.core::UIComponent/dispatchEvent()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:12266]
 at mx.core::UIComponent/set initialized()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:1577]
 at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:759]
 at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]

第166行是:

if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)

providerObj第一次为null。但是当回击并再次访问同一页面时,一切正常,并且列表中的一个提供程序被正确选择。

可能我认为第一次在填充List之前调用creationComplete处理程序方法。第二次进行调用时,将填充列表并且处理程序正常工作。如果有人可以帮助我解决这个问题,那将会很棒。

由于

哈里什

1 个答案:

答案 0 :(得分:3)

很难说出这里发生了什么,但问题在于:

providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;

该行中有很多地方可能会出现Null指针异常。

最有可能的是 - 位置practiceProvider返回的count没有设置提供商。我们无法看到这个值是如何填充的,但是如果这个代码稍后有效,我会说你发生了竞争条件 - 数据在被设置之前被访问。

至少,您应该为此添加一个guardClause:

var practiceProviders:ArrayCollection = patientDetailsModel.practiceProviderList.practiceProviders;
for (var count:int = 0; count < practiceProviders.length; ++count)
{
      providerObj = practiceProviders.getItemAt(count, 0).provider as Provider;
      if (!providerObj)
         continue;
      // etc
}  

鉴于Flex服务器调用的异步性,竞争条件有点棘手。 (我假设您正在从远程服务器加载数据)。

有两种方法可以解决这个问题 -

  • 推迟执行此方法,直到数据加载为止 - 您可以通过向RemoteService的ResultEvent添加eventListener来实现此目的

  • 第一次不要担心,但只要数据发生变化,就重新执行该方法。

例如:

protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
     dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,onCollectionChange,false,0,true);
    updateProviders();
    // Rest of existing creationComplete code moved to updateProviders();
 }
 private function updateProviders()
 {
       // Code from existing creationComplete handler goes here
 }
 private function onCollectionChange(event:CollectionEvent):void
 {
      updateProviders();
 }