Pregunta

Tengo una configuración muy simple:

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

y

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

El plunker está aquí: http://plnkr.co/edit/yRHcNGjQAq1NHDTuwXku

La transclusión en sí está funcionando, pero el {{title}} sólo se reemplaza en el modelo de la directiva.
El {{title}} Sin embargo, dentro del elemento transcluido permanece vacío aunque la directiva tenga una variable title en su alcance.¿Porqué es eso?

¿Fue útil?

Solución

El ámbito de aplicación del elemento transcluido no es un ámbito secundario de la directiva sino uno hermano.Esto es lo que dice la documentación:

En una configuración típica, el widget crea un ámbito aislado, pero la transclusión no es un elemento secundario, sino un hermano del ámbito aislado.

La solución más simple en este caso para acceder al alcance transcudido es la siguiente:

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

Manifestación: http://plnkr.co/edit/ouq9B4F2qFPh557708Q1?p=preview

Otros consejos

@dfsq tiene razón acerca de:

El alcance del elemento transcluido no es un alcance infantil de la directiva sino un hermano

Me gustaría agregar más comentarios sobre por qué este es el comportamiento esperado de angularJs.Como dicen los documentos:

En una configuración típica, el widget crea un alcance aislado, pero la transclusión no es un niño, sino un hermano del alcance de aislado.Esto hace posible que el widget tenga un estado privado, y la transclusión esté vinculada al alcance de los padres (pre-isolados).

El contenido transcluido dentro de la directiva es arbitrario, no debe tener conocimiento sobre el alcance aislado de la directiva, de lo contrario, crearíamos un código de acoplamiento apretado.Porque para que el contenido transcluido funcione, el contenido debe conocer los detalles de implementación de su directiva (lo que está disponible para usar).

Si decides que el contenido pertenece a la directiva.Tienes 2 opciones:

1) Hacer que el contenido forme parte de la plantilla.

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

MANIFESTACIÓN

2) Utilice la tranclusión personalizada para vincular el alcance usted mismo:

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

MANIFESTACIÓN

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top