0

まず、私はフレックスとアクション スクリプトにまったく慣れていないということから始めましょう。とにかく、選択した従業員を取得してフォームに入力するカスタム イベントを作成しようとしています。イベントはディスパッチされています (dispatchEvent(event) は true を返しています) が、ハンドラー内に設定されたブレークポイントにヒットすることはありません。

これが私のコードの一部です(理解を深めるために論理的に配置されています):

従業員フォーム カスタム コンポーネント

<mx:Metadata>
     [Event(name="selectEmployeeEvent", type="events.EmployeeEvent")]
<mx:Metadata>
<mx:Script>
   [Bindable]
   public var selectedEmployee:Employee;
</mx:Script>
...Form Fields

応用

<mx:DataGrid id="grdEmployees" width="160" height="268"
            itemClick="EmployeeClicked(event);">
<custom:EmployeeForm
     selectEmployeeEvent="SelectEmployeeEventHandler(event)"
     selectedEmployee="{selectedEmployee}" />

<mx:Script>
    [Bindable]
private var selectedEmployee:Employee;

private function EmployeeClicked(event:ListEvent):void
    {
     var employeeData:Employee;
     employeeData = event.itemRenderer.data as Employee;
     var employeeEventObject:EmployeeEvent = 
             new EmployeeEvent( "selectEmployeeEvent", employeeData);
     var test:Boolean = dispatchEvent(employeeEventObject);
         //test == true in debugger
}
    private function SelectEmployeeEventHandler(event:EmployeeEvent):void
    {
         selectedEmployee = event.Employee; //This event never fires
    }



</mx:Script>
4

2 に答える 2

3

ここで問題を引き起こすために共謀していることがいくつかあります。:)

まず、カスタム コンポーネントで次の宣言を行います。

<mx:Metadata>
     [Event(name="selectEmployeeEvent", type="events.EmployeeEvent")]
<mx:Metadata>

...カスタムコンポーネントがこの特定のイベントをディスパッチすることをコンパイラに通知しますが、実際には、カスタムコンポーネントではなく、含まれているドキュメントでディスパッチしています-呼び出すように設定されていないため、イベントリスナーは呼び出されませんそれ。

もう 1 つのことは、このようなリスト項目選択の状況では、より一般的な動作は、ListEvent の currentTarget の selectedItem プロパティからオブジェクトを抽出することです (つまり、グリッドと、ターゲットではなく currentTarget です。イベントバブリングの仕組み)。あなたの場合、グリッドの selectedItem プロパティには Employee オブジェクトが含まれている必要があるため (グリッドの dataProvider が Employee オブジェクトの ArrayCollection であると仮定)、次のように直接参照します。

private function employeeClicked(event:ListEvent):void
{
   var employee:Employee = event.currentTarget.selectedItem as Employee;
   dispatchEvent(new EmployeeEvent("selectEmployeeEvent"), employee);
}

データのソースとして itemRenderer を使用することは、悪名高いほど信頼性が低いことで知られています。アイテム レンダラーは、常に予測できない方法でフレームワークによって再利用される視覚要素であるためです。代わりに、上で示したようにイベントからアイテムを直接プルする方がはるかに安全です。この場合、既に Employee オブジェクトがあるため、「employeeData」オブジェクトはまったく必要ありません。

ただし、おそらく、フレームワークの動作方法にもっと沿ったアプローチを提案する方が良いかもしれません.フレームワーク。たとえば、含まれているドキュメントでは次のようになります。

<mx:Script>
    <![CDATA[

        import mx.events.ListEvent;

        [Bindable]
        private var selectedEmployee:Employee;

        private function dgEmployees_itemClick(event:ListEvent):void
        {
            selectedEmployee = event.currentTarget.selectedItem as Employee;
        }

    ]]>
</mx:Script>

<mx:DataGrid id="dgEmployees" dataProvider="{someArrayCollectionOfEmployees}" itemClick="dgEmployees_itemClick(event)" />

<custom:EmployeeForm selectedEmployee="{selectedEmployee}" />

... Bindable としてマークされた selectedEmployee メンバーを定義し、DataGrid の itemClick ハンドラーで設定します。そうすれば、EmployeeForm で指定したバインド式により、選択した従業員への参照がフォームに常に含まれるようになります。次に、フォーム自体で:

<mx:Script>
    <![CDATA[

        [Bindable]
        [Inspectable]
        public var selectedEmployee:Employee;

    ]]>
</mx:Script>

<mx:Form>
    <mx:FormItem label="Name">
        <mx:TextInput text="{selectedEmployee.name}" />
    </mx:FormItem>
</mx:Form>

... 選択した従業員を受け入れるだけです (選択した従業員に関する最新の情報がフォーム フィールドに常に表示されるように、再度バインド可能とマークされます)。

これは理にかなっていますか?アプリケーションの要件に精通していないため、単純化しすぎている可能性がありますが、これは非常に一般的なシナリオであるため、従来の方法をよりよく理解できるように、説明のためだけに代替案を提示することにしました。それを処理します。

ただし、何らかの理由でカスタム イベントをディスパッチする必要がある場合は、単に選択した項目を設定するだけでなく (たとえば、そのイベントをリッスンしている他のコンポーネントがある場合)、指定した dispatchEvent 呼び出しで問題ありません。イベントをディスパッチしているのが含まれているドキュメントであることを理解している限り、それを通知したい人は誰でもそのドキュメントに特定のリスナーを添付する必要があります:

yourContainingDoc.addEventListener("selectEmployeeEvent", yourOtherComponentsSelectionHandler);

お役に立てば幸いです -- お気軽にコメントを投稿してください。

于 2009-02-13T13:01:28.547 に答える
1

下位のコードサンプル(DataGrid、おそらく)のクラスからイベントをディスパッチしていますが、イベントはEmployeeFormクラスで定義されており、イベントハンドラーも同様にEmployeeFormインスタンスにアタッチされています。私の知る限り、イベントは階層の下ではなく上に伝播するため、フォームの親からイベントを発生させても、フォーム自体でハンドラーがトリガーされることはありません。フォームからイベントを発生させるか、イベントハンドラーを親コンポーネントにアタッチします。

于 2009-02-13T09:48:39.930 に答える