2015-08-31 15 views
6

Chcę utworzyć dyrektywę, która organizuje dane wyświetlania pogrupowane według daty. Chcę również móc określić dyrektywę, która będzie wyświetlała poszczególne wiersze. W idealnym świecie byłoby to wyglądać mniej więcej tak (ale miłą i ładną)Przekaż dane do elementu z translatorem

Friday, Oct 28 
    [some directive html] 
    [some directive html] 
    [some directive html] 
Saturday, Oct 29 
    [some directive html] 
Sunday, Oct 30 
    [some directive html] 
    [some directive html] 
... 

To oczywiście nie działa, więc jeśli masz lepsze podejście proszę mi powiedzieć, ale miałem nadzieję, że będzie w stanie zrobić coś wzdłuż tych linii:

app.directive('dateOrganized', [function(){ 
    return { 
     template: 
      '<div>' + 
       '<div ng-repeat="organizedDate in organizedDate">' + 
        '<div>{{organizedDate.date | date}}</div>' + 
        '<div ng-repeat="item in organizedDate.items">' + 
         '{{rowDirectiveHtml}}' + 
        '</div>' + 
       '</div>' + 
      '</div>', 
     scope: { 
      organizedDates: '=', 
      rowDirectiveHtml: '=' 
     } 
     ... 
    }; 
}]) 

app.directive('itemRow', [function(){ 
    return { 
     template: '<div>{{item.data}}</div>', 
     scope: { 
      item: '=' 
     } 
    }; 
}]); 

następnie używać go tak:

<div data-organized organized-dates="stuff" row-directive-html="<div item-row item=\"item\" />" /> 

wiem, że to bardzo brzydki (i nie działa, ale jestem pewien, że mogę dostać pracy z kilka poprawek), więc czym naprawdę jestem sking, czy jest lepszy sposób na zrobienie tego?

+1

Dlaczego chcesz przekazać html w 'row-dyrektywa-html'? Czy to się zmieni? – Subash

+1

Powinieneś zajrzeć do funkcji ['$ transclude'] (https://docs.angularjs.org/api/ng/service/$compile#-link-) - wprowadzonej do kontrolera lub piątego parametru do' link' funkcjonować. Powinieneś także rozważyć przekazanie szablonu (który jest tym, czym jest) jako elementu podrzędnego, a nie jako atrybutu. Ale ogólnie rzecz biorąc, dobra odpowiedź na to pytanie będzie musiała dotknąć wielu koncepcji, dlatego lepiej najpierw zapoznać się z tymi podstawowymi pojęciami. –

+0

Tak, wiersze się zmienią, więc potrzebuję elastyczności. @new dev dzięki za napiwek. Przyjrzę się temu. –

Odpowiedz

11

To pytanie jest bardziej skomplikowane niż mogłoby się wydawać, więc zróbmy to.

Co budujesz jest dyrektywa, która akceptuje częściową szablonu - <div item-row item="item" /> - i że szablon zastosowań (lub połączone przeciwko zakresie wyglądu) wewnętrzna zmienna - item - który nie jest zdefiniowany w zakresie zewnętrznej przez użytkownik; jego znaczenie jest zdefiniowane przez dyrektywę, a użytkownik "odkrywa" ją czytając dokumentację dyrektywy. Zazwyczaj nazywam takie "magiczne" zmienne z prefiksem $, np. $item.

Krok 1

Zamiast przechodzącą szablon jako HTML-as-ciąg poprzez wiązanie atrybutu, przekaż go jako zawartość i transclude tych treści. Dołączanie pozwala powiązać dołączany zawartość przed arbitralną zakresie:

<foo> 
    <div>my item is: {{$item}}</div> 
</foo> 
.directive("foo", function(){ 
    return { 
    scope: {}, 
    transclude: true, 
    template: "<h1>I am foo</h1><placeholder></placeholder>", 
    link: function(scope, element, attrs, ctrls, transclude){ 

     scope.$item = "magic variable"; 

     transclude(scope, function(clonedContent){ 
     element.find("placeholder").replaceWith(clonedContent); 
     }); 
    } 
    }; 
}); 

Powyższy umieści szablon <div>my item is: {{$item}}</div> (może być dowolny szablon określić) gdzie dyrektywa foo decyduje, i połączyć przeciwko zakres, który zdefiniowano jako $item.

Krok 2

Ale dodaje Złożoność dyrektywy jest to, że używa ng-repeat, które sama akceptuje szablon oraz szablon otrzyma swoją dyrektywa musi być używany jako szablon ng-repeat.

Dzięki powyższemu podejściu to nie zadziała, ponieważ przed upływem czasu link będzie już zawierał własne treści, zanim będzie można zastosować swoje.

Jednym ze sposobów rozwiązania to ręcznie $compile szablonu foo zamiast przy użyciu właściwości template.Przed kompilacji, będziemy mieć szansę, aby umieścić przeznaczony szablon gdzie potrzebne:

.directive("foo", function($compile){ 
    return { 
    scope: {}, 
    transclude: true, 
    link: function(scope, element, attrs, ctrls, transclude){ 

     scope.items = [1, 2, 3, 4]; 

     var template = '<h1>I am foo</h1>\ 
         <div ng-repeat="$item in items">\ 
         <placeholder></placeholder>\ 
         </div>'; 
     var templateEl = angular.element(template); 

     transclude(scope, function(clonedContent){ 
     templateEl.find("placeholder").replaceWith(clonedContent); 

     $compile(templateEl)(scope, function(clonedTemplate){ 
      element.append(clonedTemplate); 
     }); 
     }); 
    } 
    }; 
}); 

Demo

+0

To jest idealne, dziękuję. Całe powtórzenie ng mnie wyrzuciło i nie chciałem się włamać do brzydkiego rozwiązania. Po raz kolejny świetna robota. –

+0

Przyjemne rozwiązanie z dobrym wyjaśnieniem pomogło rozwiązać dokładnie ten problem w moim projekcie. –

+0

Ten sam problem, kątowy ma za dużo magii. –

Powiązane problemy