SparkリストSelectedIndexは更新されません
-
27-10-2019 - |
質問
したがって、私の問題は、2つのボタンをクリックすると実行されるnextslide()とprevslide()を使用するときにselectedindexが更新されないことです。 SelectedIndexは、リスト内の要素をクリックすると動作します。私は何が間違っているのですか?いくつかのイベントを派遣する必要がありますか?ボタンでそれを行うためのトリックはありますか?
これは私のプレイリストクラスです
public class Playlist extends List
{
private var dispatcher:Dispatcher;
public function Playlist()
{
super();
this.dragEnabled = true;
this.dragMoveEnabled = true;
this.dropEnabled = true;
this.allowMultipleSelection = true;
this.dispatcher = new Dispatcher();
}
public function handleSelection(event:PlaylistEvent):void
{
if (event.type == PlaylistEvent.ITEMS_SELECTED){
selectItem(event.index, event.count);
selectedIndex = event.index;
}
}
private function selectItem(index:Number, count:Number):void
{
var tempArray:Array = this.dataProvider.toArray();
var indiceVector:Vector.<int> = new Vector.<int>();
var itemVector:Vector.<Object> = new Vector.<Object>();
var n:int = 1;
for (var i:int=0;i<tempArray.length;i++){
var item:PlaylistItem = tempArray[i];
if (i<index) deselectItem(item);
else if (i<index+count) {
item.Selected=true;
indiceVector[count-n] = i;
itemVector[count-n++] = item;
}
else deselectItem(item);
}
selectedItems = itemVector;
selectedIndices = indiceVector;
}
private function deselectItem(item:PlaylistItem):void
{
item.Selected = false;
}
public function nextSlide():void
{
if (dataProvider.length == 0) return;
var index:int = selectedIndex;
if (index < 0) {
var event1:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, 0, 1);
dispatcher.dispatchEvent(event1);
return;
}
var item:PlaylistItem = PlaylistItem(dataProvider.getItemAt(index));
if (index < dataProvider.length-1) {
trace("going to index", index+1);
var event:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, index+1, 1);
dispatcher.dispatchEvent(event);
return;
}
}
public function previousSlide():void
{
if (dataProvider.length == 0) return;
var index:int = selectedIndex;
if (index < 0) {
var event1:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, 0, 1);
dispatcher.dispatchEvent(event1);
return;
}
var item:PlaylistItem = PlaylistItem(dataProvider.getItemAt(index));
if (index > 0) {
var event:PlaylistEvent = new PlaylistEvent(PlaylistEvent.ITEMS_SELECTED, index-1, 1);
dispatcher.dispatchEvent(event);
return;
}
}
}
}
これは私の仲間のイベントマップです
<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mate="http://mate.asfusion.com/"
xmlns:air="de.websector.mate.extensions.air.*">
<fx:Script>
<![CDATA[
import components.Playlist;
import events.PlaylistEvent;
import mx.controls.Alert;
import mx.events.*;
import mx.logging.*;
import mx.logging.Log;
import spark.components.Application;
private var logger:ILogger;
private function initLogger():void{
logger = Log.getLogger("MainEventMap");
trace("started init maineventmap");
}
]]>
</fx:Script>
<fx:Declarations>
<mate:EventHandlers type="{FlexEvent.APPLICATION_COMPLETE}">
<mate:InlineInvoker method="initLogger"/>
<mate:ObjectBuilder generator="{MainManager}"/>
<mate:EventAnnouncer type="{InitEvent.SYSTEM_INIT_COMPLETE}" />
</mate:EventHandlers>
<mate:Injectors target="{Playlist}">
<mate:PropertyInjector targetKey="dataProvider" source="{MainManager}" sourceKey="playlistItems" />
</mate:Injectors>
<mate:Injectors target="{MainManager}">
<mate:PropertyInjector targetKey="playlist" source="{Playlist}" />
</mate:Injectors>
<!-- Playlist events! __________________________________________________________________________________________________-->
<mate:EventHandlers type="{PlaylistEvent.ITEMS_SELECTED}">
<mate:MethodInvoker generator="{Playlist}" method="handleSelection" arguments="{event}" />
</mate:EventHandlers>
</fx:Declarations>
</mate:EventMap>
解決
Mateは、イベントバスへの参照でプライベートディスパッチャー変数に入れることができないため、イベントマップは、発送しているイベントを「聞く」ことはなく、メソッドを呼び出すことはできません。
これは、同じコンポーネントにメソッドを呼び出す愚かな方法のように思えます。これは、何らかの方法でロジックを分離する必要があることを知っていることを示していると思います。私が提案するのは、DataProviderとselectedIndexを含むプレゼンテーションモデルがあり、それを参照することです。次に、リストはDataProviderとSelectedIndexにバインドします。 PMは、SelectedIndexを維持するためにバスでのイベントを聴くことができます。または、ビューコンポーネントから直接操作できます。
そうすれば、ボタンが入っているリストのサブクラスを持っていることが少し問題があることに気付いたとき、問題なくリストとボタンを備えた新しいグループサブクラスを添付できます。
イベントバスを適切に注入する方法の例(PMの使用方法を便利に示している)については、チェックしてください http://www.developria.com/2010/05/refactoring-with-mate.html. 。イベントバスを理解することで良いスタートを切っているようですが、見てもう少し詳細を取得したいと思うかもしれません。 http://www.developria.com/2010/05/pass-the-eventdispatcher-pleas.html .
他のヒント
誰かが#flex(irc://irc.freenode.net/flex)で指摘したように、間違いは使用されています MethodInvoker クラスの新しいインスタンスを構築し、そのインスタンスでハンドル選択方法を実行するため。プレイリストのインスタンスをイベントマップに注入して使用することにより、この問題を解決しました InlineInvoker.
<mate:EventHandlers type="{PlaylistEvent.ITEMS_SELECTED}">
<mate:InlineInvoker method="{playlist.handleSelection}" arguments="{event}" />
</mate:EventHandlers>
そのため、問題は、FlexやDatabind、EventDispatchingではなく、MATEフレームワークの使用でした。