Conflit AngularJS-Twig avec double accolades

198

Comme vous le savez, à la fois angulaire et brindille a une construction de contrôle commune - double croisillons. Comment puis-je changer la valeur par défaut d'Angular?

Je sais que je peux le faire dans Twig, mais dans certains projets, je ne peux pas, seulement JS.

Meliborn
la source
2
doublon possible du délimiteur personnalisé Angular JS
pkozlowski.opensource
10
Une autre solution spécifique à la brindille pour la folie de la moustache consiste à utiliser la verbatimbalise; par exemple: {% verbatim %}{{ angular_var }}{% endverbatim %}pour conserver vos moustaches pour AngularJS: twig.sensiolabs.org/doc/tags/verbatim.html
Darragh Enright
Pas à l'auteur de la question, mais aux futurs lecteurs: si vous cherchez une réponse à cette question, pensez à éviter tout rendu des modèles côté serveur, si vous pouvez vous le permettre (si votre contenu principal se trouve dans la zone authentifiée ou si vous êtes le moteur de recherche principal comme source de trafic est Google (ils peuvent analyser JS SPA)).
OZ_
1
@OZ_ L'argument du moteur de recherche contre AngularJS et similaires devient assez redondant lors de l'utilisation de services comme prerender.io .
E. Sundin

Réponses:

287

Vous pouvez modifier les balises d'interpolation de début et de fin à l'aide du interpolateProviderservice. Un endroit pratique pour cela est au moment de l'initialisation du module.

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

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

abhaga
la source
5
Je n'utiliserais pas [[]], cependant. Cela pourrait être mauvais dans certaines fixations, comme celle-ci:[[myObject[myArray[index]]
Andrew Joslin
1
Vrai. J'utilise {[{}]}avec Django bien qu'il soit un peu bizarre à taper. J'ai mis à jour la réponse.
abhaga
4
Merci! Ran dans un problème similaire avec Jeykll / Liquid et Angular JS. J'ai opté pour {[et]}.
jfroom
7
Le point-virgule n'a-t-il pas besoin d'être supprimé après le} sur la ligne 3?
CashIsClay
Existe-t-il un moyen de le faire au niveau mondial dans Angular? Notre site Web comportera de très nombreux modules sur de nombreuses pages différentes, et nous ne voulons pas oublier de le faire.
theY4Kman
89

Cette question semble avoir trouvé une réponse, mais une solution plus élégante qui n'a pas été mentionnée consiste simplement à placer les accolades entre guillemets entre les accolades, comme ceci:

{{ '{{myModelName}}' }}

Si vous utilisez une variable pour le contenu, faites-le à la place:

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

Vous devez utiliser des guillemets simples , pas des guillemets doubles. Les guillemets doubles permettent l'interpolation de chaînes par Twig, vous devez donc être plus prudent avec le contenu, surtout si vous utilisez des expressions.


Si vous détestez toujours voir tous ces accolades, vous pouvez également créer une macro simple pour automatiser le processus:

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

Enregistrez-le en tant que fichier et importez-le dans votre modèle. J'utilise ngle nom car il est court et doux.

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

Ou vous pouvez mettre la macro en haut de votre modèle et l'importer en tant que _self (voir ici) :

{% import _self as ng %}

Ensuite, utilisez-le comme suit:

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

Cela produit:

{{myModelName}}

... et un suivi pour ceux qui utilisent MtHaml aux côtés de Twig. MtHaml permet d'utiliser les boucles AngularJS de la manière normale car tout code Twig est accessible via - et = au lieu de {{}}. Par exemple:

HTML simple + 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 avec brindille de style MtHaml:

- set twigVariable = "somevalue"
= twigVariable
%tr(ng-repeat="product in products")
   %td {{ product.name }}
robert.corlett
la source
6
Ce n'est peut-être pas le moyen le plus agréable, mais je pense que c'est le seul moyen de ne pas se soucier des problèmes de compatibilité. La modification de l'éther Angular ou Twig {{pourrait créer un problème de compatibilité ou une mauvaise portabilité.
Léo Benoist du

1
La solution fournie n'a commencé à fonctionner pour moi que lorsque j'ai fait ce {{'{{contact.name}\}'}} qui s'imprime {{contact.name}}comme je le voulais
Timo Huovinen

37

Comme mentionné dans une question similaire sur Django et AngularJS, une astuce avec la modification des symboles par défaut (dans Twig ou AngularJS) peut entraîner une incompatibilité avec un logiciel tiers, qui utilisera ces symboles. Donc, le meilleur conseil que j'ai trouvé dans google: https://groups.google.com/d/msg/symfony2/kyebufz4M00/8VhF1KWsSAEJ

TwigBundle ne fournit pas de configuration pour les délimiteurs de lexer car les modifier vous interdirait d'utiliser des modèles fournis par des bundles partagés (y compris les modèles d'exception fournis par TwigBundle lui-même).

Cependant, vous pouvez utiliser la balise brute autour de vos modèles angulaires pour éviter la douleur d'échapper à toutes les accolades: http://twig.sensiolabs.org/doc/tags/raw.html - Christophe | Stof

La balise a été renommée textuellement


6
Veuillez noter que la balise brute a été renommée "verbatim" pour éviter toute confusion avec le filtre brut de twig.
stedekay

3
C'est à mon avis la manière la plus propre.
kemicofa ghost du

27

Vous pouvez également utiliser la directive basée sur les attributs <p ng-bind="yourText"></p>est la même que<p>{{yourText}}</p>


4
Ce doit être la meilleure solution en fait.
Alain Jacomet Forte

5
comment l'utiliser sur attr, comme <li id={{item.id}}></li>?
gkiwi

Encore mieux serait d'utiliser <p data-ng-bind="yourText"></p>pour rendre le HTML valide
Jean-Marc Zimmer

24

Vous pouvez utiliser \{{product.name}}pour obtenir l'expression ignorée par les guidons et utilisée à la place par Angular.


C'était vraiment utile
aidan

Bonne solution - échappez simplement aux personnages réservés, fonctionne également dans les guidons
un darren

22

Ceci est une version compilée des meilleures réponses et un exemple pour les blocs textuels:

Pour les insertions simples, utilisez:

{{ '{{model}}' }}

ou si vous utilisez une variable twig

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

Verbatim , est très élégant et lisible pour plusieurs variables angulaires:

<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, ça m'a sauvé la vie. Je ne pouvais pas utiliser {{param}} dans le filtre: {{{param}}: $ select.search} et votre solution l'a corrigé. Merci
balron
19

Si vous n'êtes pas intéressé à modifier les balises de modèle de la syntaxe angulaire existante, ce qui nécessiterait une réécriture confuse de vos modèles angulaires existants.

On peut simplement utiliser les balises de modèle de brindille avec des balises angulaires comme ceci:

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

Trouvé ceci sur une autre réponse de thread similaire : Angularjs sur une application symfony2

chrisjlee
la source
1
@ThomasReggi L'OP demande une solution pour Twig. Découvrez les autres réponses qui peuvent également fonctionner pour Liquid.
Noel Llevares
18

Alternativement, vous pouvez modifier les caractères utilisés par Twig. Ceci est contrôlé par 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
la source
Très utile. Merci.
Anos K. Mhazo
17

Selon ce post, vous devriez pouvoir le faire comme ceci:

angular.module('app', [])
  .config(['$interpolateProvider', function ($interpolateProvider) {
    $interpolateProvider.startSymbol('[[');
    $interpolateProvider.endSymbol(']]');
  }]);
Olivier.Roger
la source
2
où dois-je mettre ces codes? | Oh! Je l'ai, je dois faire ng-app = app
zx1986
En commençant avec AngularJS et dans Laravel 4, j'ai chargé le framework, puis ajouté {{2 + 2}} à la vue - rien d'autre du tout et il a été évalué à 4. Où dois-je mettre le code pour changer cela en [[2+ 2]]? J'ai essayé de l'ajouter entre les balises de script sur la même page et d'ajouter ng-app = "myApp" à la balise div contenant, mais cela ne fonctionne pas.
Perkin5
Il doit être placé dans votre javascript, des contrôleurs au même endroit sont définis. Pour un exemple de travail, consultez la documentation ( docs.angularjs.org/api/ng.$interpolateProvider ) dans l'onglet script.js.
Olivier.Roger
2
Un mot d'avertissement, j'utilisais les crochets doubles pour Angular, mais je viens de rencontrer un problème avec le framework Django Message. Messages crée un cookie qui contient [[]] et Angular essaie de l'analyser et s'étouffe dans le processus. J'ai essayé de passer au stockage de session pour les messages, mais même problème. Je suis passé à des crochets triples.
Dustin
2

J'aime @pabloRN, mais je préférerais utiliser span au lieu de p, car pour moi p ajoutera une ligne au résultat.

Je vais utiliser ceci:

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

J'utilise également aText avec le curseur à l'intérieur des guillemets doubles, je n'ai donc pas à réécrire le tout encore et encore.

sifoo
la source
en fait, ng-bind = "" est ce qui compte, vous pouvez utiliser n'importe quelle balise que vous aimez :)
wesamly
@wesamly Vous pouvez utiliser n'importe quelle balise, mais elle <span>est utilisée pour le texte en ligne lorsque vous avez d'autres contenus. Par exemple:<h1>Welcome <span ng-bind="yourName"></span></h1>
rybo111
1

Vous pouvez créer une fonction en brindille pour entourer vos directives angulaires, donc comme au lieu d'aller ...

{{"angular"}}

tu vas ...

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

marcinzajkowski
la source
Veuillez utiliser le code pour bloquer l'extrait de code dans vos réponses.
β.εηοιτ.βε