0

Ich habe kürzlich ein Projekt für eine benutzerdefinierte Berichtsbenutzeroberfläche in Flex abgeschlossen. Jetzt wurde ich damit beauftragt, eine neue Anwendung zu erstellen, die im Wesentlichen eine "Lite" -Version der ursprünglichen Benutzeroberfläche ist. Es enthält nur einige der Optionen, die in der ursprünglichen Anwendung enthalten sind. Außerdem muss es eine separate Anwendung sein.Wie strukturiere ich mehrere Cairngorm MVC-Projekte, die sich mehrere Komponenten teilen?

Ich möchte meinen Code nicht duplizieren, daher plane ich, einige Klassen aus der ursprünglichen Anwendung in eine neue Bibliothek zu verschieben, die von beiden Anwendungen gemeinsam genutzt werden kann. Ich versuche jedoch herauszufinden, wie dies in meiner MVC-Umgebung funktioniert.

Zum Beispiel habe ich eine Akkordeon-Komponente, mit der Benutzer mehrere Elemente filtern können. Jedes Accordion-Kind ist eine Instanz einer benutzerdefinierten Komponente mit zwei Listen (eine für Entitäten, die für die Auswahl verfügbar sind, die andere für die Entitäten, die der Benutzer ausgewählt hat). Jede untergeordnete Komponente besitzt an das Modell gebundene Eigenschaften und Funktionen, die Cairngorm-Ereignisse aufrufen.

Hier ist ein vereinfachtes Beispiel:

FiltersAccordion.mxml: 
<?xml version="1.0" encoding="utf-8"?> 
<mx:Accordion xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:local="*"> 
    <mx:Script> 
     <![CDATA[ 
      import model.ModelLocator; 

      [Bindable] 
      private var __model:ModelLocator = ModelLocator.getInstance(); 
     ]]> 
    </mx:Script> 

    <local:GenreFilter availableGenres="{__model.availableGenres}" 
     selectedGenres="{__model.selectedGenres}" /> 

    <local:ArtistFilter availableArtists="{__model.availableArtists}" 
     selectedArtists="{__model.selectedArtists}" /> 

    <local:LabelFilter availableLabels="{__model.availableLabels}" 
     selectedLabels="{__model.selectedLabels}" /> 
</mx:Accordion> 


GenreFilter.mxml: 

<?xml version="1.0" encoding="utf-8"?> 
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Script> 
     <![CDATA[ 
      import control.events.AddGenresEvent; 
      import control.events.RemoveGenresEvent; 

      import model.ModelLocator; 

      [Bindable] 
      private var __model:ModelLocator = ModelLocator.getInstance(); 

      [Bindable] 
      public var availableGenres:ArrayCollection; 

      [Bindable] 
      public var selectedGenres:ArrayCollection; 

      private function addGenresButton_clickHandler():void 
      { 
       var event:AddGenresEvent = new AddGenresEvent(); 

       event.availableGenres = availableGenres; 

       event.selectedGenres = selectedGenres; 

       event.itemsToAdd = availableGenresList.selectedItems; 

       event.dispatch(); 
      } 

      protected function removeGenresButton_clickHandler():void 
      { 
       var event:RemoveGenresEvent = new RemoveGenresEvent(); 

       event.availableGenres = availableGenres; 

       event.selectedGenres = selectedGenres; 

       event.itemsToRemove = selectedGenresList.selectedItems; 

       event.dispatch(); 
      } 

     ]]> 
    </mx:Script> 

    <mx:List id="availableGenresList" dataProvider="{availableGenres}" /> 

    <mx:VBox> 
     <mx:Button id="addButton" icon="{rightArrowIcon}" width="22" 
      height="22" click="addGenresButton_clickHandler();" /> 

     <mx:Button id="removeButton" icon="{leftArrowIcon}" width="22" 
      height="22" click="removeGenresButton_clickHandler();" /> 
    </mx:VBox> 

    <mx:List id="selectedGenresList" dataProvider="{selectedGenres}" 
     width="100%" height="100%" allowMultipleSelection="true" /> 
</mx:HBox> 

ArtistFilter.mxml und LabelFilter.mxml ziemlich das gleiche Design wie sind GenreFilter.mxml, aber auf ihre spezifischen Ereignisse verwenden.

Also wie soll ich das tun? Es macht keinen Sinn, mein Model in die Shared Library zu verschieben. Ich möchte im Grunde nur View-Komponenten in der Bibliothek erstellen. Bin ich total von meinem Rocker weg oder was?

Antwort

2

Das ist einer der großen Fehler von Cairngorm - Ihre Ansichten sind an Ihr Modell gebunden. Das heißt, Sie können eine Menge Schmerz lindern, indem Sie die wiederverwendbaren Komponenten allgemeiner und verkapselter machen. Dann erweitern Sie sie, um sie mit dem Rest der App zu verbinden.

also Ihre erste Komponente wird:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Accordion xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:local="*"> 
    <mx:Script> 
     <![CDATA[ 
      [Bindable] 
      public var availableGenres:ArrayCollection; 

      [Bindable] 
      public var availableArtists:ArrayCollection; 

      [Bindable] 
      public var availableLabels:ArrayCollection; 

      [Bindable] 
      public var selectedGenres:ArrayCollection; 

      [Bindable] 
      public var selectedArtists:ArrayCollection; 

      [Bindable] 
      public var selectedLabels:ArrayCollection; 
     ]]> 
    </mx:Script> 

    <local:GenreFilter availableGenres="{availableGenres}" 
     selectedGenres="{selectedGenres}" /> 

    <local:ArtistFilter availableArtists="{availableArtists}" 
     selectedArtists="{selectedArtists}" /> 

    <local:LabelFilter availableLabels="{availableLabels}" 
     selectedLabels="{selectedLabels}" /> 
</mx:Accordion> 

Dann Sie tun dies in jeder Anwendung (aber mit unterschiedlichen Modellen/Veranstaltungen).

<library:SpecialAccordion ... 
    availableGenres="{_model.availableGenres}" 
    availableArtists="{_model.availableArtists}" 
    ... etc ... 
    > 

    <mx:Script> 
     <![CDATA[ 
      import model.ModelLocator; 

      [Bindable] 
      private var __model:ModelLocator = ModelLocator.getInstance(); 
     ]]> 
    </mx:Script> 

</library:SpecialAccordion> 

Macht das Sinn? Es ist der Unterschied zwischen einer "Ansicht" und einer "Komponente". Komponenten können wiederverwendet werden, Ansichten dagegen nicht. Komponenten sind gekapselt, Ansichten sind anwendungsspezifisch.

+0

Sie treffen den Nagel auf den Kopf: ModelLocator ist nur globale Variablen verkleidet. –

Verwandte Themen