¿Cómo usar la función 'reemplazar' para directivas AngularJS personalizadas?

91

¿Por qué tiene replace=trueo replace=falseno algún impacto en el siguiente código?

¿Por qué no se muestra "algo de contenido existente" cuando replace = false?

O, para decirlo de manera más humilde, ¿podría explicarnos amablemente cuál es la replace=true/falsefunción de las directivas y cómo utilizarla?

Ejemplo

JS / Angular:

<script>
    angular.module('scopes', [])
          .controller('Ctrl', function($scope) {
                $scope.title = "hello";

          })
          .directive('myDir', function() {
            return {
              restrict: 'E',
              replace: true,
              template: '<div>{{title}}</div>'
            };
      });
</script>

HTML:

<div ng-controller="Ctrl">
    <my-dir><h3>some existing content</h3></my-dir>
</div>

Véalo en Plunker aquí:

http://plnkr.co/edit/4ywZGwfsKHLAoGL38vvW?p=preview

Tostada Kaya
fuente
2
@georgeawg marcó esto como un duplicado de otra pregunta que se hizo / respondió en una fecha posterior a esta pregunta.
Kaya Toast

Respuestas:

189

Cuando tienes replace: true, obtienes la siguiente pieza de DOM:

<div ng-controller="Ctrl" class="ng-scope">
    <div class="ng-binding">hello</div>
</div>

mientras que, con replace: falseobtienes esto:

<div ng-controller="Ctrl" class="ng-scope">
    <my-dir>
        <div class="ng-binding">hello</div>
    </my-dir>
</div>

Entonces, la replacepropiedad en las directivas se refiere a si el elemento al que se está aplicando la directiva ( <my-dir>en ese caso) debe permanecer ( replace: false) y la plantilla de la directiva debe agregarse como su hijo,

O

el elemento al que se aplica la directiva debe ser reemplazado ( replace: true) por la plantilla de la directiva.

En ambos casos se perderán los hijos del elemento (al que se aplica la directiva). Si quisiera conservar el contenido / los niños originales del elemento, tendría que transludirlo. La siguiente directiva lo haría:

.directive('myDir', function() {
    return {
        restrict: 'E',
        replace: false,
        transclude: true,
        template: '<div>{{title}}<div ng-transclude></div></div>'
    };
});

En ese caso, si en la plantilla de la directiva tiene un elemento (o elementos) con atributo ng-transclude, su contenido será reemplazado por el contenido original del elemento (al que se está aplicando la directiva).

Ver ejemplo de translusión http://plnkr.co/edit/2DJQydBjgwj9vExLn3Ik?p=preview

Vea esto para leer más sobre la translusión.

kamilkp
fuente
6
Esta es una explicación maravillosamente simple. Y muchas gracias por aclarar la transclusión también.
Kaya Toast
Más importante aún, ¿por qué no se explica en docs.angularjs.org/guide/directive y por qué esta respuesta no se vincula a una respuesta definitiva sobre el tema?
Trindaz
3
@Trindaz replaceha quedado obsoleto desde AngularJS v1.3 ( enlace ).
Tonči D.
33

replace:true es obsoleto

De los Docs:

replace ([¡DEPRECADO!], Se eliminará en la próxima versión principal, es decir, v2.0)

especifique qué debe reemplazar la plantilla. Por defecto es false.

  • true - la plantilla reemplazará el elemento de la directiva.
  • false - la plantilla reemplazará el contenido del elemento de la directiva.

- API de directiva integral de AngularJS

Desde GitHub:

Caitp: está en desuso porque se conocen problemas muy tontos con replace: true, algunos de los cuales no se pueden solucionar de manera razonable. Si tiene cuidado y evita estos problemas, entonces tendrá más poder, pero para beneficio de los nuevos usuarios, es más fácil decirles "esto le dará dolor de cabeza, no lo haga".

- Problema AngularJS # 7636


Actualizar

Nota: replace: trueestá obsoleto y no se recomienda su uso, principalmente debido a los problemas enumerados aquí. Se ha eliminado por completo en el nuevo Angular.

Problemas con reemplazar: verdadero

Para más información, ver

Georgeawg
fuente
2
Sigo leyendo que se supone que esto es compatible de manera no oficial en Angular 2, pero no puedo averiguar cómo activarlo. ¿Alguien puede decirme cuál es la sintaxis?
devios1
@devios Necesito tal cosa para mis componentes mdl, pero actualmente estoy usando la remove-hostsolución stackoverflow.com/questions/34280475/… si averigua cómo activar replace: trueen A2, avísenos.
kuncevic.dev