AngularJs Übergabe komplexer Daten an die Direktive


76

Ich habe folgende Richtlinie:

<div teamspeak details="{{data.details}}"></div>

Dies ist die Objektstruktur:

data: {
                details: {
                    serverName: { type: 'text', value: 'my server name' },
                    port: { type: 'number', value: 'my port' },
                    nickname: { type: 'text' },
                    password: { type: 'password' },
                    channel: { type: 'text' },
                    channelPassword: { type: 'password' },
                    autoBookmarkAdd: { type: 'checkbox' }
                }
}

und ich möchte, dass es einen Link basierend auf den Daten innerhalb des data.detailsObjekts generiert . Leider funktioniert es nicht, da ich irgendwie nicht auf innere Werte des detailsObjekts zugreifen kann , aber wenn ich es übergebe, eine einfache Datenstruktur wie:

<div teamspeak details="{{data.details.serverName.value}}"></div>

Ich kann mit darauf zugreifen {{details}}.

Hier ist mein Richtliniencode:

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        scope: {
            details: '@details',
        },
        link: function (scope, element, attrs) {
        }
    };
});

Vielen Dank

Antworten:


106

Lesen Sie auf Angularjs offizielle Website Erklärung:

@ oder @attr - Binden Sie eine lokale Bereichseigenschaft an den Wert des DOM-Attributs. Das Ergebnis ist immer eine Zeichenfolge, da DOM-Attribute Zeichenfolgen sind. Wenn kein attr-Name angegeben wird, wird angenommen, dass der Attributname mit dem lokalen Namen übereinstimmt. Gegebene und Widget-Definition des Bereichs: {localName: '@ myAttr'}, dann spiegelt die Widget-Bereichseigenschaft localName den interpolierten Wert von hallo {{name}} wider. Wenn sich das Namensattribut ändert, ändert sich auch die Eigenschaft localName im Widget-Bereich. Der Name wird aus dem übergeordneten Bereich (nicht aus dem Komponentenbereich) gelesen.

Sie können also nur eine Zeichenfolge senden. Um ein Objekt zu übergeben, müssen Sie eine bidirektionale Bindung mit einrichten =.

   scope: {
        details: '=',
    },

Und Ihr HTML wird so aussehen

<div teamspeak details="data.details"></div>

2
Dies scheint mit TypeScript nicht zu funktionieren. Ich habe eine Schnittstelle erstellt, die den Umfang definiert. In dieser Schnittstelle habe ich ein benutzerdefiniertes Objekt. Wenn Sie die Schnittstelle dem Bereich object = '='zuweisen , kann ich dies nicht tun , da Sie einem Typobjekt keine Zeichenfolge zuweisen können ObjectType. Irgendwelche Vorschläge, wie das mit TypeScript geht?
Bilo-Io

Es kann auch mit Bindungen gemacht werden: {} Ich werde eine Antwort posten, sobald ich sie zum Laufen bringe :)
Sonic Soul

39

Jemand fragte, wie es geht, ohne den Umfang zu isolieren. Hier ist eine Lösung:

<div teamspeak details="{{data.details}}"></div>

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        link: function (scope, element, attrs) {
            if(attrs.details){
                scope.details = scope.$eval(attrs.details);
            }
        }
    };
});

Wir können sogar verwenden, $interpolatewenn Werte in attrs.detailsdynamisch mit eckigen {{...}} Ausdrücken festgelegt werden sollen ...

scope.details = scope.$eval($interpolate(attrs.details)(scope));

(Vergessen Sie nicht, den $interpolateDienst in Ihre Richtlinie aufzunehmen.)

Wichtiger Hinweis: Ich habe diese Methode nicht mit Winkel 2 getestet.


1
Wenn Sie attrs verwenden, fällt es Ihnen schwer, diese Direktive in Winkel 2 umzuwandeln. Dies ist nur ein persönlicher Hinweis.
Peter Huang

danke @ sh977218, ich habe einen Hinweis hinzugefügt, dass diese Methode nicht mit Winkel 2 getestet wird
plong0
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.