2013-09-25 14 views
19

Aufgabe:Angular Richtlinie mit mehreren Vorlagen

  • Kontakt zu zeigen.
  • Kontakt ist JSON-Daten, sagen wir {Name: "Mark", Standort: "England", Telefone: [...]}. compact/detailliert/verstärkte mit zusätzlichen Informationen (gemeinsame Kontakte - zusätzliche Richtlinie)

Weil Kontakt auf verschiedenen Seiten an verschiedenen Orten gezeigt werden, könnte es natürlich Richtlinie zu erstellen ist:

  • Kontakt auf vielfältige Weise konnte gezeigt werden, (Widget) für den Kontakt, aber hier ist die Frage: "Wie das gleiche Widget mit mehreren Vorlagen zu organisieren?"

    Optionen:

    1. Erstellen einer Richtlinie mit einer Vorlage, das versteckt Abschnitte nach Kontakt „type“-große Vorlage mit möglicherweise vielen ng-Schalter und ng-wenn
    2. Erstellen Sie eine Richtlinie für jede Vorlage - fast gleiche Direktiven mit nur anderen Vorlage (oder templateURL)
    3. Um load templates dynamically while linking-hat Probleme mit Einbindung und Ersetzen (Verschmelzung Attribute)

    Was ist Ihre expirience mit diesem Problem zu lösen?

  • +0

    Müssen Sie eine Vorlage in die Richtlinie einfügen? Können Sie einfach eine Direktive als Attribut neben einem ng-include für Ihre Vorlage verwenden? –

    +0

    Sprichst du über [Lösung vorgeschlagen von Adam hier] (http://codepen.io/anon/pen/tabcx)? – SpeedShifter

    Antwort

    17

    Persönlich denke ich, dass Option 2 eine saubere Trennung zwischen den Anzeigemodi bietet. Ich habe eine working CodePen example erstellt, um zu illustrieren, wie Sie dies sauber erreichen können, indem Sie für jede Vorlage separate Anweisungen verwenden.

    Die Methode, die ich in meinem CodePen-Beispiel verwendet habe, verwendet eine Vorlagenfabrik, die über Angular DI in jede Anweisung eingefügt wird. Die Template-Factory-Implementierung ist sehr sauber, da sie nur ng-include Template-Strings für jeden der verschiedenen unterstützten Anzeigemodi verwendet (kompakt & detailliert). Die eigentlichen HTML-Templates (Teiltöne) können in externen View-Dateien oder internen Script-Blöcken untergebracht werden.

    die Kontakt Direktiven sind einfach:

    <contact compact ng-repeat="contact in contacts" ng-model="contact"></contact> 
    

    Dies schafft eine kompakte Version der Kontaktliste.

    <contact detailed ng-repeat="contact in contacts" ng-model="contact"></contact> 
    

    Dies erstellt eine detaillierte Kontaktliste.

    Ich gebe zu, dass ich Code wie diese nicht zur Produktion eingesetzt habe, so dass es Skalierbarkeit oder andere Bedenken geben kann, die ich nicht berücksichtigt habe. Ich hoffe, der Code, den ich zur Verfügung gestellt habe, beantwortet Ihre Fragen oder bietet zumindest Anregungen für weitere Erkundungen.

    +0

    Danke für die Antwort auch mit Beispiel). Ihr Recht, wenn die Direktiven so klein sind, ist es nicht entscheidend, einen für jeden Typ zu haben, aber es gibt Flexibilität, um einen von ihnen nur dann zu verbessern, wenn es notwendig ist. – SpeedShifter

    +0

    Nur ich kann hinzufügen, Was für ng-include als Vorlage zu verwenden? Warum nicht "Templates" factory nur als map "Kontakttyp" => "url to template" benutzen, siehst du irgendeinen Gewinn davon? – SpeedShifter

    +0

    wow - machte meinen Tag – alonisser

    11

    ich bauen einen neuen Ansatz auf Adam Beispiel arbeiten und auch unter Verwendung der Probe von Winkel docs, in dem sie über Funktionen in templateUrl Eigenschaft sprechen https://docs.angularjs.org/guide/directive, ist dies die Plunker von Winkel docs: http://plnkr.co/edit/h2CSf2WqCLYfPvzL9WQn?p=preview

    .directive('myCustomer', function() { 
        return { 
         templateUrl: function(elem, attr){ 
         return 'customer-'+attr.type+'.html'; 
         } 
        }; 
        }); 
    

    Und dies ist meine remixed Lösung:

    http://codepen.io/anon/pen/wawOyz?editors=101

    app.factory('templates', function() { 
        return { 
        compact: 'compact', 
        detailed: 'detailed' 
        }; 
    }); 
    
    app.directive('contact', function(templates) { 
        return { 
        restrict: 'E', 
        templateUrl: function($elem, $attr){ 
         return templates[$attr.mode];  
        }, 
        scope: { 
         contact: '=ngModel' 
        } 
        }; 
    }); 
    

    I t gefallen Die Idee, alle Vorlagenadressen in einer Fabrik zu haben, aber ich finde die Direktive pro Modus ziemlich repetitiv und wenn Sie mehrere Elemente haben, die diese Methode verwenden, müssen Sie sie mit einem Namensraum versehen (Kontakttext, E-Mail-Text, Firmentext) sie stürzen nicht ab.

    Ich bin mir noch nicht sicher, ob dies ein besserer Weg zu gehen ist, ist kürzer und mehr trocken, aber vielleicht ist es schwieriger zu testen oder weniger anpassbar. Ich wollte nur den Ansatz teilen, falls er irgendjemandem helfen kann.

    Verwandte Themen