Question

J'ai une configuration très simple :

<pane title="mytitle">Title in parent (transcluded): {{title}}</pane>

et

angular.module('transclude', [])
 .directive('pane', function(){
    return {
      restrict: 'E',
      transclude: true,
      scope: { title:'@' },
      template: '<div>' +
                  '<div>Title in isolated scope: {{title}}</div>' +
                  '<div ng-transclude></div>' +
                '</div>'
    };
});

Le plunker est ici : http://plnkr.co/edit/yRHcNGjQAq1NHDTuwXku

La transclusion elle-même fonctionne mais le {{title}} n'est remplacé que dans le modèle de la directive.
Le {{title}} à l'intérieur de l'élément transclus reste cependant vide même si la directive a une variable title dans sa portée.Pourquoi donc?

Était-ce utile?

La solution

La portée de l'élément transclus n'est pas une portée enfant de la directive mais une portée sœur.Voici ce que dit la documentation :

Dans une configuration typique, le widget crée une portée isolée, mais la transclusion n'est pas un enfant, mais un frère de la portée isolée.

La solution la plus simple dans ce cas, pour accéder à la portée transcue, est la suivante :

.directive('pane', function () {
    return {
        restrict: 'E',
        transclude: true,
        scope: {
            title: '@'
        },
        template:
            '<div>' +
                '<div>Title in isolated scope: {{title}}</div>' +
                '<div ng-transclude></div>' +
            '</div>',
        link: function (scope, element, attrs) {
            scope.$$nextSibling.title = attrs.title;
        }
    };
});

Démo : http://plnkr.co/edit/ouq9B4F2qFPh557708Q1?p=preview

Autres conseils

@dfsq a raison sur :

La portée de l'élément transclué n'est pas une portée d'enfant de la directive mais un frère

J'aimerais ajouter plus de commentaires sur les raisons pour lesquelles il s'agit du comportement attendu d'angularJs.Comme le dit la documentation :

Dans une configuration typique, le widget crée une portée d'isolat, mais la transclusion n'est pas un enfant, mais un frère ou une sœur de la portée de l'isolat.Cela permet au widget d'avoir un état privé et à la transclusion d'être liée à la portée parent (pré-isolé).

Le contenu transclus à l'intérieur de la directive est arbitraire, il ne devrait pas avons connaissance de la portée isolée de la directive, sinon nous créerions un code de couplage serré.Parce que pour que le contenu transclus fonctionne, le contenu doit connaître les détails d'implémentation de votre directive (ce qui est disponible à utiliser).

Si vous décidez que le contenu fait parti à la directive.Vous avez 2 options :

1) Intégrez le contenu au modèle

    angular.module('transclude', [])
         .directive('pane', function(){
            return {
              restrict: 'E',
              transclude: true,
              scope: { title:'@' },
              template: '<div>' +
                          '<div>Title in isolated scope: {{title}}</div>' +
                          '<div>' +
                             ' Title in parent (transcluded): {{title}} ' +
                         ' </div>' +
                        '</div>'
            };
   });

DÉMO

2) Utilisez une transcription personnalisée pour lier vous-même la portée :

angular.module('transclude', [])
     .directive('pane', function(){
        return {
          restrict: 'E',
          transclude: true,
          scope: { title:'@' },
          template: '<div>' +
                      '<div>Title in isolated scope: {{title}}</div>' +
                      '<div class="transclude"></div>' +
                    '</div>',
        link: function (scope, element, attr,controller, linker) {
           linker(scope, function(clone){
                  element.find(".transclude").append(clone); // add to DOM
           });
          }
        };
    });

DÉMO

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top