12

Próbuję rozszerzyć funkcjonalność tabular-ui tabs i mam problemy z jej zawijaniem.Owijanie dyrektywy zestawu tabular-ui i napotkanie błędów "Wiele dyrektyw z prośbą o błędy dotyczące zakrycia/izolowanego zakresu"

Ten plunker jest dyrektywa tabset un-owinięty:

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

Ten plunker zawiera moja pierwsza próba zawijania dyrektywę tabset:

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

Początkowe podejście owijania prosto - opakowanie do przodu. Ale ... Wprowadzam dodatkowe elementy div w szablonie zastępowania, aby uniknąć "Wielokrotnych dyrektyw z prośbą o izolowany zakres" i "Wiele dyrektyw z prośbą o transclusion" o błędy kątowe i aby upewnić się, że nastąpiło transclusion.

Kluczowe fragmenty kodu:

.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>' 
    }; 
}); 

Myślę jednak, że dodatkowe DIV w szablonie są przyczyną problemów. Oto nieopakowany tabset z dodatkowymi divami w miejscach, do których mój szablon je doda.

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

więc logiczną rzeczą jest wyeliminowanie div ... ale to gdzie ja potrzebuję pomocy. Czy ktokolwiek wie o tym w czysty sposób, nie uderzając w "Wielokrotne dyrektywy proszące o izolowany zakres" i "Wielokrotne dyrektywy domagające się" wykluczenia "błędów kątowych. Oto jedna nieudana próba.

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

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

BTW, w przypadku, gdy zastanawiasz się, co próbuję zrobić, mój koniec celem jest użyć atrybutu tabManager przekazany do urlTabset do automatycznego wypełnienia pól w zakładce dyrektywy (zapakowane przez urlTab). Aby być bardziej konkretny to co mam zmierzające do:

.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>' 
    }; 
}); 

Szablon powyżej oczywiście nie działa, ale to daje istotę tego, co próbuję zrobić.

I nie mam problemu z rozwiązaniem, które wymaga, aby dyrektywa pakowania nie miała izolowanego zakresu. Mogę to obejść, przechowując stan w kontekście kontrolera.

Odpowiedz

5

Jeśli próbujesz zwiększyć funkcjonalność angular-ui, może lepiej będzie zrobić to za pomocą dyrektyw atrybutów niż zupełnie nowych elementów. Mogę się mylić, ale wygląda na to, że nie zamierzasz zmieniać ogólnej struktury DOM, zamiast zastąpić twoją dyrektywę kanciastymi. Na przykład użycie znaczników HTML B1 nie oznacza, że ​​nie trzeba już wykonywać żadnego uzupełnienia lub wymiany szablonu. To pozwoliłoby uniknąć tego wszystkiego razem.

To pozostawia problem izolowanego zakresu dla atrybutów, których chcesz użyć do rozszerzenia.Zamiast tego, możesz użyć scope: true, aby pobrać ten sam wyizolowany zakres, co tab i tabset (chociaż nie możesz tutaj definiować powiązań) i możesz uzyskać atrybuty tak, jak gdybyś użył normalnych wartości powiązanych, używając $parse i attrs.

Twoje dyrektywy (z funkcjonalnością twojego drugiego plunkera) kończą na szukaniu czegoś takiego.

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

Dziękuję przede wszystkim za odpowiedź. Doceniam to. Mój plunker został uproszczony z tego, co chciałem zrobić - czyli użyć stanu tabManager (określonego w urlTabset), aby automatycznie wypełnić atrybuty w dyrektywie zakładki (opakowane przez urlTab). Więc nie jest to ścisłe powiększanie. Oznacza to, że to podejście nie będzie dla mnie skuteczne. Jakieś inne pomysły? – Amir

+0

Myślę, że jeśli to tylko dodawanie atrybutów, można to zrobić za pomocą 'attrs' zamiast używać szablonu. Dopóki twoja dyrektywa jest na tym samym elemencie, który chcesz zmienić. – Andyrooger

+0

Interesujące. Sugerujesz w fazie kompilacji dodawanie atrybutów, więc gdy opakowana dyrektywa przetworzy je w swojej funkcji kompilacji/linku, zobaczy je. Ale to nie będzie obsługiwać zmiennych w izolowanym zakresie zawijanej dyrektywy, jak "wybierz" dla karty. A może skoro kompilacje są zamówione, to wszystko trenuje. Wciąż jest trochę odurzająco. Nie chciałbym robić czegoś takiego "". Chcę prawdziwego owijania, aby html wyglądał na czysty "". Doceniam jednak Twój wysiłek/dzielenie się pomysłami. Mam nadzieję, że istnieje prosty sposób na uzyskanie czystego opakowania. – Amir

Powiązane problemy