1

次のように、View クラス EmployeeList があります。

<?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: null オブジェクト参照のプロパティまたはメソッドにアクセスできません。cafeparsley.view::EmployeeList/_EmployeeList_List1_i() [C:\dev\code\workspace\Examples\CafeParsley\src\cafeparsley\view\EmployeeList.mxml:29] で cafeparsley.view::EmployeeList/_EmployeeList_Array2_c() で mx .core::DeferredInstanceFromFunction/getInstance()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\DeferredInstanceFromFunction.as:105] spark.components::SkinnableContainer/createDeferredContent()[E :\dev\4.x\frameworks\projects\spark\src\spark\components\SkinnableContainer.as:985] 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.

そのため、エラーがスローされた場合、employeeListPM は null です。ただし、コンポーネントをコメントアウトし <s:List>、再実行して init メソッドにブレークポイントを設定すると、init() が呼び出されます。したがって、コンテキスト構成が間違っているわけではありません。PM が時間内に注入されておらず、エラーがスローされているだけです。しかし、パセリのマニュアルによると、自動配線を使用するか<parsley:configure/>、PM が必要になるまでに注入する必要があります。

比較的些細な依存性注入シナリオだと思っていたもので、何が間違っているのかわかりません。手伝ってくれますか?

4

2 に答える 2

1

ここにいくつかのポイント:

あなたの例には<Configure />or<FastInject />タグが含まれていませんが、投稿でそれらについて言及しているので、サンプルコードから欠落しているだけだと思います。(そうでない場合は、これを機能させるためにこれらの1つを追加する必要があります)。

ただし、コードに競合状態がある可能性が高くなります。

具体的には、次の行です。

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

Modelは注入されたプロパティですが、コードが最初に実行されたときに注入されたことが保証されているわけではありません。

代わりに、nullチェックを実行するクラス内のスクリプトにコードを移動してから、ロジックをPMに戻します。

すなわち:

labelFunction="nameFunction"


private function nameFunction(item:Object):String
{
    return (model) ? model.properName(item) : "";
}
于 2011-09-08T22:31:15.193 に答える
0

考慮すべきもう1つのことは、Parsley [Init]メタタグでマークされたビューの関数からmodel.init()を呼び出していることです。同じ[Init]メタタグをモデルのinit()メソッドに適用することをお勧めします。

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

ビューからmodel.init()を呼び出すのではなく、これを行います。また、ライフサイクルのドキュメントには次のように記載されています。

[Init]でマークされたメソッドは、オブジェクトがインスタンス化され、すべてのインジェクションが処理された後に呼び出されます。

挿入されたオブジェクト間でinit()メソッドを直接呼び出すのではなく、メタデータタグアプローチを利用することで、はるかに一貫した結果が得られました。

于 2011-09-13T20:20:50.080 に答える