En utilisant angularjs avec turbolinks
Je suis en train d'utiliser Angularjs cadre de mon application avec turbolinks. Après le changement de page n'est pas d'initialiser de nouveaux eventlisteners. Est-il de toute façon pour le faire fonctionner? Merci à l'avance!
- Serait-ce une bonne idée d'utiliser turbolinks avec le framework MVC sur le client. Est turbolinks pas question de réduire le Javascript pour mettre à nu le minimum pour obtenir un avantage de codage seulement en Ruby pour servir des pages du client ainsi que l'exécution de code serveur ?
Vous devez vous connecter pour publier un commentaire.
AngularJS vs Turbolinks
Turbolinks ainsi que AnguluarJS peut à la fois être utilisé pour réaliser une application web de réagir plus rapidement, dans le sens que, en réponse à une interaction de l'utilisateur que quelque chose se passe sur la page web sans recharger et de nouveau rendu de la page entière.
Ils diffèrent dans la suite de propos:
AngularJS vous aide à construire un riche de l'application côté client, où vous écrire beaucoup de code JavaScript qui s'exécute sur la machine client. Ce code rend le site interactif de l'utilisateur. Il communique avec le serveur-côté backend, c'est à dire avec l'application Rails, à l'aide d'une API JSON.
Turbolinks, d'autre part, contribue à rendre le site interactif sans vous demander de code JavaScript. Il vous permet de en tenir à la Ruby/Rails de code exécuter sur le serveur-côté et encore, "comme par magie", l'utilisation d'AJAX pour le remplacer, et donc rerender, seules les parties de la page qui ont changé.
Où Turbolinks est forte en vous permettant d'utiliser ce puissant AJAX mécanisme sans rien faire à la main et du code Ruby/Rails, il pourrait venir d'un stade, en tant que votre demande se développe, où vous souhaitez intégrer un framework JavaScript comme AngularJS.
Surtout dans cette étape intermédiaire, où vous souhaitez intégrer successivement AngularJS dans votre application, un seul composant à la fois, il peut faire parfaitement sens pour exécuter Angular JS et Turbolinks ensemble.
Comment utiliser AngularJS et Turbolinks ensemble
Utiliser le callback manuellement bootstrap Angulaire
Dans votre Angulaire de code, vous avez une ligne de la définition de votre module d'application, quelque chose comme ceci:
Ce code est exécuté lorsque la page est chargée. Mais depuis Turbolinks remplace simplement une partie de la page et empêche tout un chargement de la page, vous devez prendre soin de, l'angulaire de l'application est correctement initialisé ("bootstrap"), même après que ces partielle de la recharge effectuée par Turbolinks. Ainsi, remplace le module de déclaration par le code suivant:
Ne pas bootstrap automatiquement
Vous voyez souvent dans les tutoriels comment bootstrap Angulaire app automatiquement en utilisant le
ng-app
attribut dans votre code HTML.Mais l'utilisation de ce mécanisme avec le manuel de bootstrap illustré ci-dessus pourrait entraîner l'application de bootstrap deux fois et, par conséquent, frein à l'application.
Ainsi, il suffit de retirer cette
ng-app
attribut:Lecture
ng-click="save()"
puis recharge la vue... ma méthode save() maintenant le feu à trois reprises. Des idées?<head>
section de notre admin (donc, la prévention de plusieurs instanciations de mes scripts). Ce n'est pas un public en face de l'expérience donc je ne suis pas trop préoccupé par les pièges de chargement JS dans le code html de la section de la tête.Uncaught Error: [ng:btstrpd] App Already Bootstrapped with this Element 'document'
. Apparemment, un élément ne peut être démarré une fois. Changerangular.bootstrap(document, ['YourApplication'])
àangular.bootstrap("body", ['YourApplication'])
semble fonctionner sans aucun problème.$(document).on
ligne, et a ajouté une$ ->
au lieuunless $('body').hasClass('ng-scope')
(coffeescript!) après angulaire.bootstrap$(document).on "turbolinks:load", -> …
. Merci!$(document).on('turbolinks:load', function() { angular.bootstrap(document.body, ['myApp']); })
Merci!Turbolinks tenter d'optimiser le rendu des pages et serait en conflit avec la normale ou initier d'AngularJS.
Si vous utilisez Turbolinks dans certains endroits de votre application et certaines parties Anguleuses. Je propose cette solution élégante:
Chaque lien vers une page qui est angularapp (où vous utilisez ng-app="appname") devrait avoir cet attribut:
La deuxième sur Stackoverflow est explicitement rechargement/amorçage chaque ng-app par la page de traitement:la charge de l'événement. Je voudrais que l'intrusif, ne pas mentionner que vous êtes potentiellement chargement de quelque chose qui n'est pas sur une page où le gaspillage des ressources.
J'ai personnellement utilisé la solution ci-dessus.
Espère que cela aide
En cas de bug
après la mise à niveau vers angulaire 1.2.x vous pouvez utiliser ci-dessous pour résoudre le problème.
Dans le précédent post @nates proposé de modifier
angular.bootstrap(document, ['YourApplication'])
àangular.bootstrap("body", ['YourApplication'])
mais cela provoque un flash de non contenu.Turbolinks n'est pas tout à fait faire du sens avec un framework MVC côté client. Turbolinks est utilisé pour foirer le tout, mais le corps de la réponse du serveur. Côté client MVC, vous devriez juste être de passage JSON pour le client, pas en HTML.
Dans tous les cas, turbolinks crée ses propres rappels.
La jquery.turbolinks plugin peut déclencher l'amorçage de modules via ng-app directives. Si vous essayez de les faire manuellement bootstrap vos modules, jquery.turbolinks peut conduire à la ng:btstrpd erreurs. Une mise en garde que j'ai trouvé est que jquery.turbolinks s'appuie sur la
page:load
de l'événement, ce qui peut déclencher avant toute nouvelle page spécifique<script>
les balises de fin de l'exécution. Cela peut conduire à$injector:nomod
erreurs si vous incluez module de définitions à l'extérieur de la application.js. Si vous voulez vraiment les modules définis dans la séparer les fichiers javascript qui ne sont inclus sur certaines pages, vous pouvez simplement désactiver turbolinks sur tous les liens vers ces pages viadata-no-turbolink
.Ajouter le gestionnaire d'événement suivant votre demande.
Coffeescript:
Javascript:
Ce sera la cause de l'angle de l'application pour être démarré après chaque page chargée par Turbolinks.
De crédit à https://gist.github.com/ayamomiji/4736614
$(document).on('ready', bootstrapAngular)
.ready
etpage:change
Sur la base des commentaires que j'ai vu, la seule valable scénario pour l'utilisation à la fois dans une voie où Angulaire serait en conflit avec Turbolinks (comme l'endroit où je me permettre Angulaire pour gérer certains de routage) est si j'ai une application que je suis en train de port Angulaire.
Personnellement, si je devais le faire à partir de zéro, je pense que la meilleure solution serait de décider de ce qui doit gérer le routage et le bâton avec qui. Si Angulaire, que de se débarrasser de Turbolinks -> il n'a pas beaucoup de sens pour vous, si vous avez quelque chose à proximité d'une seule page de l'app. Si vous vous permettez de Rails pour gérer le routage, alors il suffit d'utiliser Angulaire d'organiser comportement côté client ne peuvent pas être traitées par le serveur au moment de servir les modèles.
Ai-je raté un scénario, ici? Il ne semble pas élégant à moi pour essayer de diviser le routage des responsabilités entre les différents cadres, même dans une grande demande... Est-il un autre scénario où Turbolinks pourrait interférer avec Angulaire autre que l'actualisation de la page ou de naviguer vers une nouvelle route?
À l'aide de Turbolinks et AngularJS ensemble
+1 pour @fiedl pour une grande réponse. Mais ma préférence est de faire usage de
page:change
de concert avecpage:load
parce que cela offre une certaine souplesse: le DOM peut recevoir unpage:load
événement à partir de sources autres que turbolinks, de sorte que vous pourriez voulez pas avoir le même rappel de feu.Regarder pour un
page:change
, puis unpage:load
devrait restreindre votre rappel de comportement uniquement turbolinks-à l'instigation des événements.(Cela permettra de/vous obliger à garder votre
ng-app
déclaration dans votre code html, comme d'habitude lorsque l'on travaille avec AngularJS.)https://github.com/turbolinks/turbolinks#turbolinks
Ainsi, au lieu d'ajouter
ng-app
directive sur la<html>
élément, on peut juste le faire sur le<body>
élément.