2012-01-29 64 views
0

我正在編寫使用可擴展UI元素的應用程序,其精確實現是在運行時使用配置確定的。例如,我想顯示一個項目列表,這些項目取決於配置,可能會顯示爲項目符號列表,編號列表,列列表等等。包含的應用程序對特定實現一無所知,除了它是一種支持方法調用setItems(items:Array):void的類型。指定跨SWF邊界的類型變量中斷

所以我已經建立了一個基類,例如:

package my.stuff { 
    public class BaseList extends MovieClip { 
     protected var m_items:Array; 
     public function BaseList() { 
      m_items = new Array(); 
     } 
     public function setItems(items:Array):void { 
      for (var i:int = 0; i < items.length; i++) 
       m_items.push(items[i]); 
     } 
    } 
} 

然後,我已創建一個專門的實現,做,例如,兩列的列表:

package my.stuff { 
    public class TwoColumnList extends BaseList { 
     protected var m_columns:Array; 
     public function TwoColumnList() { 
      super(); 
      m_columns = new Array(); 
      m_columns.push(new Array()); 
      m_columns.push(new Array()); 
     } 
     public override function setItems(items:Array):void { 
      for (var i:int = 0; i < items.length; i++) { 
       m_items.push(items[i]); 
       m_columns[i%2].push(items[i]); 
      } 
     } 
    } 
} 

現在UI本身在Flash Professional中作爲具有類TwoColumnList的FLA作爲「文檔類」完成。我將FLA(「發佈」)編譯到目標SWF,然後嘗試將其加載到應用程序中。一般情況下我希望這像這樣的工作:

public function startLoading(implURL:String):void) { 
    var loader:Loader = new Loader(); 
    loader.contentLoaderInfo.addEventListener(Event.INIT, doneLoadingImpl); 
    loader.load(new URLRequest(implURL)); 
} 

public function doneLoadingImpl(e:Event) { 
    var info:LoaderInfo = e.target as LoaderInfo; 
    var impl:DisplayObject = info.content; 
    m_containerClip.addChild(impl); 
    var listImpl:BaseList = impl as BaseList; 
    impl.setItems(m_allItems); 
} 

除了這並不工作 - addChild()工作正常,但劇組到BaseList結果null(也不例外 - 只是null)。我可以投implMovieClip就好了,我也可以將它轉換目錄到TwoColumnList,之後它蒙上向上竭盡所能BaseList,像這樣:

... 
var listImpl:BaseList = impl as TwoColumnList; 
... 

所以這樣的作品,但它確實違背了目的整個練習 - 這是而不是提前知道可能在將來創建的特定UI實現。

我讀了一些關於做info.applicationDomain.getDefinition的地方,但我不能說它有任何影響。

我在日常工作中不是一個ActionScript開發人員,我剛剛被邀請去幫助一些其主要開發人員不再在公司工作的項目,而且我很難 - 任何幫助都會讚賞。

回答

1

您的問題很可能與加載到不同應用程序域中的類有關。如果對象不是要投射到的類的子類,則類型轉換將返回null,並且似乎您有兩個版本的BaseList「彼此競爭」。

如果是這樣的話,你可以解決它通過明確的加載SWF到相同的應用領域爲主體的一個:

var ldrContext : LoaderContext = new LoaderContext (false, ApplicationDomain.currentDomain); 
var loader:Loader = new Loader(); 
loader.contentLoaderInfo.addEventListener(Event.INIT, doneLoadingImpl); 
loader.load(new URLRequest(implURL), ldrContext); 

然而,特別是加載外部內容時,你應該使用接口。保持實現解耦正是他們發明的。檢查出this blog page,它解釋了爲什麼你應該在加載外部文件時使用接口(還有一個關於接口的更基本信息的鏈接),順便說一下,作者好像有類似於你的問題......;)

+0

@weltraumpiray:通常你說的話聽起來像個好主意,所以我會接受答案,但這確實不是真正的問題。實際的問題是我很笨 - 通過編譯FLA和我在FlashBuilder中構建的類來創建視覺效果,但必須將FLA設置爲引用正確的源代碼目錄,否則Flash Professional會忽略事實上,它沒有看到指定「文檔類」的類實現,並且愉快地編譯了一個沒有代碼的存根。在「ActionScript設置」中解決了源代碼目錄設置後,一切都按照我的預期工作。 :-) – Guss 2012-01-30 10:12:17

+0

@Guss:謝謝,看起來你的問題確實是兩個不同的BaseLists競爭;)你應該考慮接口 - 將同一個類編譯成多個SWF並不是一個好主意。 – weltraumpirat 2012-01-30 10:45:09

+0

感謝@weltraumpirat,但在特定情況下(不是在示例代碼中),基類提供了大量邏輯,專業化僅用於將FLA中的可視化設計「粘合」到基類中的邏輯中(以及提供一些指標的專業化和一些小的行爲)。 – Guss 2012-01-30 14:51:40