AngularJS-Twig en conflicto con llaves dobles

198

Como saben, tanto angular como la ramita tienen una construcción de control común: llaves dobles. ¿Cómo puedo cambiar el valor predeterminado de Angular?

Sé que puedo hacerlo en Twig, pero en algunos proyectos no puedo, solo JS.

Meliborn
fuente
2
posible duplicado del delimitador personalizado Angular JS
pkozlowski.opensource
10
Otra solución específica de ramita para la locura del bigote es usar la verbatimetiqueta; por ejemplo: {% verbatim %}{{ angular_var }}{% endverbatim %}para preservar sus bigotes para AngularJS: twig.sensiolabs.org/doc/tags/verbatim.html
Darragh Enright
No para el autor de la pregunta, sino para los futuros lectores: si está buscando una respuesta a esta pregunta, considere evitar el procesamiento de plantillas en el lado del servidor, si puede permitírselo (si su contenido principal está dentro de la zona autenticada o su motor de búsqueda principal) como fuente de tráfico es Google (pueden analizar JS SPA)).
OZ_
1
@OZ_ El argumento del motor de búsqueda contra AngularJS y similares se vuelve bastante redundante cuando se utilizan servicios como prerender.io .
E. Sundin

Respuestas:

287

Puede cambiar las etiquetas de interpolación de inicio y fin utilizando el interpolateProviderservicio. Un lugar conveniente para esto es en el momento de inicialización del módulo.

angular.module('myApp', []).config(function($interpolateProvider){
    $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});

https://docs.angularjs.org/api/ng/provider/$interpolateProvider

abhaga
fuente
55
Sin embargo, no usaría [[]]. Podría ser malo en algunos enlaces, como este:[[myObject[myArray[index]]
Andrew Joslin
1
Cierto. Lo uso {[{}]}con Django, aunque es un poco extraño escribir. He actualizado la respuesta.
abhaga
44
¡Gracias! Se encontró con un problema similar con Jeykll / Liquid y Angular JS. Opté por {[y]}.
jfroom
77
¿No es necesario eliminar el punto y coma después del} en la línea 3?
CashIsClay
¿Hay alguna manera de hacer esto a nivel global en Angular? Nuestro sitio web tendrá muchos, muchos módulos en muchas páginas diferentes, y no queremos olvidar hacer esto.
theY4Kman
89

Esta pregunta parece contestada, pero una solución más elegante que no se ha mencionado es simplemente encerrar las llaves entre comillas entre las llaves, así:

{{ '{{myModelName}}' }}

Si está utilizando una variable para el contenido, haga esto en su lugar:

{{ '{{' ~ yourvariable ~ '}}' }}

Debe usar comillas simples , no comillas dobles. Las comillas dobles permiten la interpolación de cadenas por Twig, por lo que debe tener más cuidado con el contenido, especialmente si está utilizando expresiones.


Si todavía odias ver todas esas llaves, también puedes crear una macro simple para automatizar el proceso:

{% macro curly(contents) %}
   {{ '{{' ~ contents ~ '}}' }}
{% endmacro %}

Guárdelo como un archivo e impórtelo a su plantilla. Estoy usando ngel nombre porque es corto y dulce.

{% import "forms.html" as ng %}

O puede colocar la macro en la parte superior de su plantilla e importarla como _self (ver aquí) :

{% import _self as ng %}

Luego úsalo de la siguiente manera:

{{ ng.curly('myModelName') }}

Esto produce:

{{myModelName}}

... y un seguimiento para aquellos que usan MtHaml junto a Twig. MtHaml permite el uso de curvas AngularJS de la manera normal porque se accede a cualquier código Twig - y = en lugar de {{}}. Por ejemplo:

HTML sin formato + AngularJS:

<tr ng-repeat="product in products">
   <td> {{ product.name }} </td>
</tr>

MtHaml + AngularJS:

%tr(ng-repeat="product in products")
   %td {{ product.name }}

MtHaml + AngularJS con ramita de estilo MtHaml:

- set twigVariable = "somevalue"
= twigVariable
%tr(ng-repeat="product in products")
   %td {{ product.name }}
robert.corlett
fuente
66
Tal vez no sea la forma más agradable, pero creo que es la única forma de no preocuparnos por problemas de compatibilidad. Ether modificar Angular o Twig {{podría crear un problema de compatibilidad o mala portabilidad.
Léo Benoist

1
La solución proporcionada solo comenzó a funcionar para mí cuando hice esto {{'{{contact.name}\}'}} que imprime {{contact.name}}como quería
Timo Huovinen

37

Como se mencionó en una pregunta similar sobre Django y AngularJS, el truco para cambiar los símbolos predeterminados (en Twig o AngularJS) puede proporcionar incompatibilidad con el software de terceros, que utilizará estos símbolos. Así que el mejor consejo que encontré en google: https://groups.google.com/d/msg/symfony2/kyebufz4M00/8VhF1KWsSAEJ

TwigBundle no proporciona una configuración para los delimitadores lexer, ya que cambiarlos le prohibiría usar plantillas proporcionadas por paquetes compartidos (incluidas las plantillas de excepción proporcionadas por TwigBundle).

Sin embargo, puede usar la etiqueta sin formato alrededor de sus plantillas angulares para evitar el dolor de escapar de todas las llaves: http://twig.sensiolabs.org/doc/tags/raw.html - Christophe | Stof

La etiqueta fue renombrada literalmente


66
Tenga en cuenta que la etiqueta sin formato se ha renombrado como "textualmente" para evitar confusiones con el filtro sin formato de ramita.
stedekay

3
Esta es, en mi opinión, la forma más limpia.
kemicofa fantasma

27

También puede usar la directiva basada en atributos <p ng-bind="yourText"></p>es la misma que<p>{{yourText}}</p>


44
Esta debe ser la mejor solución en realidad.
Alain Jacomet Forte

55
¿Cómo usarlo en Attr <li id={{item.id}}></li>?
gkiwi

Aún mejor sería usar <p data-ng-bind="yourText"></p>para hacer que el HTML sea válido
Jean-Marc Zimmer

24

Puede usar \{{product.name}}para obtener la expresión ignorada por Handlebars y utilizada por Angular en su lugar.


Esto fue realmente útil
aidan

Buena solución: simplemente escapa de los personajes reservados, también funciona en Handlebars
un oscuro

22

Esta es una versión compilada de las mejores respuestas y un ejemplo para bloques literales:

Para inserciones individuales, use:

{{ '{{model}}' }}

o si usas una variable ramita

{{ '{{' ~ twigVariableWitModelName ~ '}}' }}

Verbatim , es muy elegante y legible para varias variables angulares:

<table ng-table>
    {% verbatim %}
        <tr ng-repeat="user in $data">
        <td data-title="'Name'">{{user.name}}</td>
        <td data-title="'Age'">{{user.age}}</td>
        </tr>
    {% endverbatim %}
</table>

Ah, este fue el salvavidas para mí. No pude usar {{param}} dentro del filtro: {{{param}}: $ select.search} y su solución lo solucionó. Gracias
balron
19

Si no está interesado en cambiar las etiquetas de plantilla de la sintaxis angular existente que requeriría una reescritura confusa de sus plantillas angulares existentes.

Uno puede usar las etiquetas de plantilla de ramita con etiquetas angulares de esta manera:

{% verbatim %}{{yourName}}{% endverbatim %}

Encontré esto en otra respuesta de hilo similar : Angularjs en una aplicación symfony2

chrisjlee
fuente
1
@ThomasReggi El OP está pidiendo una solución para Twig. Vea las otras respuestas que también pueden funcionar para Liquid.
Noel Llevares
18

Alternativamente, puede cambiar los caracteres utilizados por Twig. Esto es controlado por Twig_Lexer .

$twig = new Twig_Environment();

$lexer = new Twig_Lexer($twig, array(
    'tag_comment'   => array('[#', '#]'),
    'tag_block'     => array('[%', '%]'),
    'tag_variable'  => array('[[', ']]'),
    'interpolation' => array('#[', ']'),
));
$twig->setLexer($lexer);
Arnold Daniels
fuente
Muy útil. Gracias.
Anos K. Mhazo
17

De acuerdo con esta publicación , deberías poder hacerlo así:

angular.module('app', [])
  .config(['$interpolateProvider', function ($interpolateProvider) {
    $interpolateProvider.startSymbol('[[');
    $interpolateProvider.endSymbol(']]');
  }]);
Olivier.Roger
fuente
2
¿Dónde debo poner estos códigos? El | ¡Oh! Lo tengo, tengo que hacer ng-app = app
zx1986
Comenzando con AngularJS y dentro de Laravel 4, cargué el marco y luego agregué {{2 + 2}} a la vista, nada más y lo evalué a 4. ¿Dónde pongo el código para cambiar esto a [[2+ 2]]? Intenté agregarlo entre las etiquetas de script en la misma página y agregar ng-app = "myApp" a la etiqueta div que lo contiene, pero no funciona.
Perkin5
Debe colocarse en su javascript, se definen los mismos controladores de lugar. Para un ejemplo de trabajo, mire la documentación ( docs.angularjs.org/api/ng.$interpolateProvider ) en la pestaña script.js.
Olivier.Roger
2
Una advertencia: estaba usando los corchetes dobles para Angular, pero me encontré con un problema con el marco de mensajes de Django. Messages crea una cookie que contiene [[]] y Angular intenta analizarla y se ahoga en el proceso. Intenté cambiar al almacenamiento de sesión para mensajes, pero el mismo problema. Cambié a corchetes triples.
Dustin
2

Me gusta @pabloRN, pero preferiría usar span en lugar de p, porque para mí p agregará una línea al resultado.

Usaré esto:

<span ng-bind="yourName"></span>

También uso aText con el cursor dentro de la comilla doble para no tener que reescribir todo una y otra vez.

sifoo
fuente
ng-bind = "" es lo que importa, puedes usar cualquier etiqueta que quieras :)
wesamly
@wesamly Puede usar cualquier etiqueta, pero <span>se usa para texto en línea cuando tiene otro contenido. Por ejemplo:<h1>Welcome <span ng-bind="yourName"></span></h1>
rybo111
1

Puede crear una función en rama para rodear sus directivas angulares, así que en lugar de ir ...

{{"angular"}}

anda tu ...

{{angular_parser("angular stuff here output curlies around it")}}

marcinzajkowski
fuente
El código de usuario bloquea el fragmento de código en sus respuestas.
β.εηοιτ.βε