12

Ich versuche, die eckigen-ui Tabset-Funktionalität zu erweitern und ich habe Probleme mit dem Wrapping es.Wrapping der eckigen-ui-Tabset-Direktive und die "Multiple Direktiven fragen nach transclusion/isolated scope" -Fehler

Diese Plunker ist die tabset Richtlinie un-wrapped:

http://plnkr.co/edit/AhG3WVNxCal5fZOUbSu6?p=preview

Diese Plunker mein erster Versuch enthält in die tabset Richtlinie Verpackung:

http://plnkr.co/edit/naKXbeVOS8nizwDPUrkT?p=preview

Der anfängliche Wickel Ansatz ist gerade -weiteres Umbrechen Aber ... ich führe zusätzliche Divs in der Ersatzvorlage ein, um die Winkelfehler "Mehrere Direktiven, die nach isolierten Bereichen fragen" und "Mehrere Direktiven, die nach Transklusion fragen" zu vermeiden, und um sicherzustellen, dass die Übernahme erfolgt.

Key Code-Schnipsel:

.directive('urlTabset', function() { 
    return { 
    restrict: 'E', 
    transclude: true, 
    replace: true, 
    scope: { 
     tabManager: '=' 
    }, 
    controller: [ "$scope", function($scope) { 
     var tabManager = $scope.tabManager; 
    }], 
    template: 
     '<div>' + 
     '<tabset>' + 
      '<div ng-transclude>' + 
      '</div>' + 
     '</tabset>' + 
     '</div>' 
    }; 
}) 

.directive('urlTab', function() { 
    return { 
    require: '^urlTabset', 
    restrict: 'E', 
    transclude: true, 
    replace: true, 
    scope: { tabName: '@' }, 
    link: function(scope, element, attrs, urlTabsetCtrl) { 
    }, 
    template: 
     '<div>' + 
     '<tab>' + 
      '<div ng-transclude>' + 
      '</div>' +     
     '</tab>' + 
     '</div>' 
    }; 
}); 

Aber ich denke, die zusätzlichen divs in der Vorlage Probleme verursachen. Hier ist das ausgepackte Tabset mit zusätzlichen Divs an den Stellen, an denen meine Vorlage sie hinzufügen würde.

http://plnkr.co/edit/kjDs7xJcZqltCAqUSAmX?p=preview

So ist die logische Sache ist es, die divs zu beseitigen ... aber das ist, wo ich die Hilfe benötigen. Kennt jemand einen sauberen Weg, dies zu tun, ohne die Winkelfehler "Mehrfachdirektiven, die um isolierten Umfang bitten" und "Mehrfachdirektiven, die um Einfügung bitten" zu treffen. Hier ist ein fehlgeschlagener Versuch.

http://plnkr.co/edit/0C6lFNhfdTVcF7ahuN3G?p=preview

Error: Multiple directives [urlTab, tab] asking for transclusion on: <tab class="ng-isolate-scope ng-scope"> 

BTW, falls Sie sich fragen, was ich versuche, mein Endziel zu tun, ist das tabManager Attribut urlTabset zu übergeben zu verwenden, automatisch ausfüllen Felder in der Registerkarte Richtlinie (Umwickelt von urlTab). Um konkreteres das ist, was ich bin mit dem Ziel:

.directive('urlTab', function() { 
    return { 
    require: '^urlTabset', 
    restrict: 'E', 
    transclude: true, 
    replace: true, 
    scope: { tabName: '@' }, 
    link: function(scope, element, attrs, urlTabsetCtrl) { 
     scope.tabs = urlTabsetCtrl.tabs; 
     scope.tabSelected = urlTabsetCtrl.tabSelected; 
    }, 
    template: 
     '<tab active="tabs[tabName].active" disabled="tabs[tabName].disabled" select="tabSelected(tabName)" ng-transclude>' + 
     '</tab>' 
    }; 
}); 

Die Vorlage oben offensichtlich nicht funktioniert, aber es gibt Ihnen das Wesentliche, was ich versuche zu tun.

Und ich bin in Ordnung mit einer Lösung, die die Wrapping-Richtlinie erfordert nicht isoliert Bereich. Ich kann das umgehen, indem ich den Status im Controller-Kontext speichere.

Antwort

5

Wenn Sie versuchen, die Funktionalität von angular-ui zu erweitern, können Sie es besser mit Attributierungsdirektiven als mit brandneuen Elementen machen. Ich mag mich vielleicht irren, aber es sieht so aus, als ob Sie nicht beabsichtigen, die allgemeine Struktur des DOM zu ändern, außer Ihre Direktive durch die von Angular-Ui zu ersetzen. Wenn Sie zum Beispiel den HTML-Code verwenden, bedeutet dies, dass Sie keine weiteren Vorlagen mehr austauschen müssen. Dies würde dieses Problem alle zusammen vermeiden.

Dadurch bleibt das Problem des isolierten Bereichs für Attribute, die Sie für die Augmentation verwenden möchten.Anstatt dies zu verwenden, können Sie scope: true verwenden, um den gleichen isolierten Bereich wie tab und tabset zu greifen (obwohl Sie hier keine Bindungen definieren können) und Sie können Attribute erhalten, wie Sie normale gebundene Werte verwenden würden, indem Sie $parse und attrs verwenden.

Ihre Anweisungen (mit der Funktionalität von Ihrem zweiten Plocker) sehen dann am Ende aus wie folgt.

angular.module('plunker', ['ui.bootstrap']) 

.directive('urlTabset', function() { 
    return { 
    restrict: 'A', 
    require: 'tabset', // Confirm the directive is only being used on tabsets 
    controller: [ "$scope", "$attrs", function($scope, $attrs) { 
     var tabManagerGetter = $parse($attrs.tabManager); // '=' 
     this.getTabManager = function() { 
     return tabManagerGetter($scope); 
     }; 

     // fun stuff here 
    }] 
    }; 
}) 

.directive('urlTab', function() { 
    return { 
    require: ['tab', '^urlTabset'], 
    restrict: 'A', 
    link: function(scope, element, attrs, ctrls) { 
     var urlTabsetCtrl = ctrls[1]; 

     function getTabName() { 
     return attrs.tabName; // '@' 
     } 

     var tabManager = urlTabsetCtrl.getTabManager(); 

     // fun stuff here 
    } 
    }; 
}); 
+0

Danke zuerst für Ihre Antwort. Ich schätze es. Mein Plunker wurde von dem, was ich tun wollte, vereinfacht - das heißt, den tabManager -Status (in urlTabset angegeben) zum automatischen Auffüllen von Attributen in der Tab-Direktive (umhüllt von urlTab) zu verwenden. Es ist also keine strenge Augmentation. Bedeutung dieser Ansatz wird nicht für mich arbeiten. Irgendwelche anderen Ideen? – Amir

+0

Ich denke, wenn man nur Attribute hinzufügt, kann man das über "attrs" tun, anstatt die Vorlage zu verwenden. Solange Ihre Direktive auf demselben Element wie das ist, das Sie ändern möchten. – Andyrooger

+0

Interessant. Sie schlagen in der Kompilierphase das Hinzufügen von Attributen vor, wenn die Wrapped-Direktive sie in ihrer Compile/Link-Funktion verarbeitet, sieht sie sie. Dies wird jedoch nicht mit Variablen im isolierten Bereich der umschlossenen Direktive umgehen, wie 'Auswahl' für die Registerkarte. Oder vielleicht, da Kompilationen bestellt werden, wird es alles Training sein. Trotzdem ist es ein bisschen hacky. Ich möchte nicht so etwas wie "" machen müssen. Ich möchte echte Verpackung, so dass die HTML sauber aussieht "". Aber ich schätze deine Bemühungen/Ideen teilen. Ich hoffe, es gibt einen einfachen Weg, um eine saubere Verpackung zu erreichen. – Amir