2011-09-08 27 views
1

我有一個視圖類EmployeeList的如下:香菜依賴注入的問題,使用Presentation Model模式

<?xml version="1.0" encoding="utf-8"?> 
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:parsley="http://www.spicefactory.org/parsley" 
        xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"> 


    <fx:Script> 
     <![CDATA[ 
      import cafeparsley.model.EmployeeListPM; 

      [Inject] 
      [Bindable] 
      public var model : EmployeeListPM; 

      [Init] 
      public function init() : void { 
       model.init(); 
      } 


     ]]> 
    </fx:Script>  

    <s:Panel title="Employee List" horizontalCenter="0"> 
     <s:HGroup paddingTop="50"> 
      <s:Button label="Add New Employee" click="model.addNewEmployee()" /> 
      <mx:Spacer width="100%" /> 
      <s:Button label="Logout" click="model.logout()" /> 
      <mx:Spacer width="100%" height="20" /> 
     </s:HGroup> 
     <s:List id="empList" dataProvider="{ model.employees }" labelFunction="model.properName" 
       change="model.initUpdateEmployee(empList.selectedItem);empList.selectedIndex = -1;" width="100%" /> 
     <s:Label id="error" color="0xFF0000" /> 
    </s:Panel> 

</s:NavigatorContent> 

的PM看起來是這樣的:

package cafeparsley.model 
{ 
    import cafeparsley.events.EmployeeEvent; 
    import cafeparsley.events.NavigationEvent; 
    import cafeparsley.services.impl.EmployeeServiceImpl; 
    import cafeparsley.vo.Employee; 

    import flash.events.EventDispatcher; 

    import mx.collections.ArrayCollection; 
    import mx.rpc.IResponder; 

    [Bindable] 
    [Event(name="navigationEvent", type="cafeparsley.events.NavigationEvent")] 
    [ManagedEvents("navigationEvent")] 
    public class EmployeeListPM extends EventDispatcher implements IResponder 
    { 

     public var employeeService : EmployeeServiceImpl = new EmployeeServiceImpl(); 

     public var employees : ArrayCollection; 

     public function init() : void 
     { 
      loadEmployees(); 
     } 


     public function EmployeeListPM() 
     { 
     } 

     public function loadEmployees():void 
     { 
      employeeService.loadEmployees(this); 
     } 

不管我是否使用或自動裝配執行注入時,當我運行此我收到以下錯誤信息:

TypeError:錯誤#1009:無法訪問空對象引用的屬性或方法。在cafeparsley.view :: EmployeeList/_EmployeeList_Array2_c()上的cafeparsley.view :: EmployeeList/_EmployeeList_List1_i()[C:\ dev \ code \ workspace \ Examples \ CafeParsley \ src \ cafeparsley \ view \ EmployeeList.mxml:29] ( ) at spark.components :: SkinnableContainer/createDeferredContent在mx.core :: DeferredInstanceFromFunction/getInstance()[E:\ dev \ 4.x \ frameworks \ projects \ framework \ src \ mx \ core \ DeferredInstanceFromFunction.as:105] ()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:985] at spark.components :: SkinnableContainer/createContentIfNeeded()[E:\ dev \ 4。 x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:1014] at spark.components :: SkinnableContainer/createChildren()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:827] at mx.core :: UIComponent/initialize()[E:\ dev \ 4.x \ frameworks \ projects \ framework \ src \ mx \ core \ UIComponent.as:7349] at mx.core :: UIComponent/http ://www.adobe.com/2006/flex/mx/internal :: childAdded()[E:\ dev \ 4.x \ frameworks \ projects \ framework \ src \ mx \ core \ UIComponent.as:7241] 在spark.components :: Group/addDisplayObjectToDisplayList(mx.core :: UIComponent/addChildAt()[E:\ dev \ 4.x \ frameworks \ projects \ framework \ src \ mx \ core \ UIComponent.as:6947] )在spark.components :: Group/http://www.adobe.com/2006/上的[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ Group.as:1825] 在spark.components :: Group/setMXMLContent()中使用flex/mx/internal :: elementAdded()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ Group.as:1416] [E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ Group.as:512] 在spark.components :: Group/set mxmlContent()[spark.parts:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ Group.as:452] at spark.components :: SkinnableContainer/set spark.components :: SkinnableContainer/createDeferredContent()[E:\ dev \ 4]中的mxmlContent()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:604] .x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:986] at spark.components :: SkinnableContainer/createContentIfNeeded()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:1014] at spark.components :: SkinnableContainer/createChildren()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ SkinnableContainer.as:827 ] at spark.components :: NavigatorContent/createChildren()[E:\ dev \ 4.x \ frameworks \ projects \ spark \ src \ spark \ components \ NavigatorContent.as :225] at mx.core :: UIComponent/initialize()[cafeadrsley.view :: E:\ dev \ 4.x \ frameworks \ projects \ framework \ src \ mx \ core \ UIComponent.as:7349] :: EmployeeList/initialize()

所以employeeListPM在拋出錯誤時爲null。但是,如果我註釋掉了組件,請在init方法中重新運行並設置斷點,init()將被調用。所以這並不是說我的上下文配置是錯誤的,只是PM沒有及時注入並且拋出錯誤。但根據歐芹手冊,如果我使用自動裝配或<parsley:configure/>,PM應該在需要的時候注入。

我看不出我在做什麼錯在我認爲是一個相對平凡的依賴注入場景。你能幫我嗎?

回答

1

幾個點的位置:

您的例子不包括<Configure /><FastInject />標籤,但是既然你提到他們在您的文章,我會認爲他們只是從示例代碼丟失。 (如果沒有,那麼你需要添加一個這樣的工作)。

但是,更有可能的是,您的代碼中存在競爭條件。

具體而言,這些行:

labelFunction="model.properName" 
change="model.initUpdateEmployee(empList.selectedItem);empList.selectedIndex = -1;" 

Model是注入的性質,然而,它不能保證在該代碼是第一次運行的時間已經注入。

而是將代碼移入執行空檢查的類中的腳本,然後將邏輯推遲迴到PM。

即:

labelFunction="nameFunction" 


private function nameFunction(item:Object):String 
{ 
    return (model) ? model.properName(item) : ""; 
} 
0

另一個要考慮的是,你在呼喚從視圖的標有香菜[初始化]元標記功能model.init()。我建議你將同樣的[Init]元標籤應用到模型的init()方法。

[Init]  
public function loadEmployees():void { 
    employeeService.loadEmployees(this); 
} 

這樣做,而不是從視圖中調用model.init()。本書雖然生命週期文檔指出:

The methods marked with [Init] get invoked after the object has been instantiated and all injections have been processed.

我有沒有調用任何的init()直接,而是利用元數據標籤的方法注入對象之間的方法更加一致的結果。