2015-08-31 30 views
6

Tarihe göre gruplandırılmış bir görüntü verisi düzenleyen bir direktif oluşturmak istiyorum. Ayrıca, tek tek satırları gösterecek bir yönergeyi belirtmek istiyorum. Mükemmel bir dünyada daha iyi bir yaklaşım varsa söyle lütfen bu nedenle,Verileri transcluded öğeye geçirme

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] 
... 

Bu açıkça çalışmaz (güzel ve hoş ama) böyle bir şey olmazdı, ama ben yapabilmek umuyordum bu satırlar boyunca bir şey: böyle

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: '=' 
     } 
    }; 
}]); 
sonra

kullanmak:

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

Ben bu süper çirkin (ve çalışmıyor biliyorum, ama bunun çalışmayı alabilir eminim birkaç tweaks) gerçekten ne olduğumu sking, bunu yapmak için daha iyi bir yolu var mı?

+1

Neden 'satır yönerge-html' içinde html geçmek istiyoruz? Değişecek mi? – Subash

+1

['$ transclude' işlevi] 'ne bakmalısınız (https://docs.angularjs.org/api/ng/service/$compile#-link-) - bir denetleyiciye veya 5. bağlantıya" bağlantıya "enjekte edilir işlevi. Bir şablonu (bir özelliktir) bir öznitelik yerine bir alt öğe olarak geçirmeyi de düşünmelisiniz. Fakat genel olarak, bu soruya iyi bir cevap vermek, bir takım kavramlara değinmek zorunda kalacaktır, bu yüzden, önce bu temel kavramları tanımak daha iyidir. –

+0

Evet, satırlar değişecek ve esnek olmaya ihtiyacım var. @new dev bahşiş için teşekkürler. Ben ona bakacağım. –

cevap

11

Bu soru göründüğünden daha karmaşıktır, bu yüzden onu bozalım.

Ne bina kısmi şablon kabul eden bir yönergesidir - <div item-row item="item" /> - ve kullanım şablon (ya da bir kapsam karşı bağlı), bir iç değişken - item - Bununla dış kapsamında tanımlanmamıştır Kullanıcı; onun anlamı sizin direktifiniz tarafından belirlenir ve kullanıcınız direktifinizin belgelerini okuyarak "keşfeder". Önceden bir $, ör. $item.

Aşama 1 yerine bağlanmasını özelliğiyle bir HTML olarak-string gibi bir şablon geçen içeriği olarak geçer ve bu içerik transclude.

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

yukarıdaki direktif foo karar verir (belirlediğiniz herhangi bir şablon olabilir) şablonu <div>my item is: {{$item}}</div> yerleştirir ve karşı bağlanacak: transcluding Eğer keyfi bir kapsam karşı çapraz dahil içeriği bağlamak sağlar $item tanımlanmış bir kapsam.

Adım

2 Ama direktifin eklenen karmaşıklığı bir şablon kabul kendisi tarafından hangi ng-repeat kullanır ve sizin yönergesi ihtiyaçlarını aldığı şablon ng-repeat bir şablon olarak kullanılacak olmasıdır. Eğer senin uygulamak için bir fırsat bulamadan

yukarıda sadece yaklaşımla, bu kez link koşuyla beri, işe yaramaz, ng-repeat zaten kendi içeriği çapraz dahil olacaktır.

$compile, template özelliğinin yerine foo şablonunun el ile yapılmasının bir yoludur.derleme önce, gerekli amaçlanan şablonu yerleştirmek için bir şans olacaktır:

.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

Bu mükemmel, teşekkürler. Bütün ng-tekrarı beni fırlatıyordu ve çirkin bir çözümde hacklemek istemedim. Bir kez daha, harika bir iş. –

+0

İyi bir açıklama ile güzel bir çözüm, projemdeki kesin sorunu çözmeye yardımcı oldu. –

+0

Aynı problem, açısal çok fazla sihir var. –