Flux de travail et structure de projet AngularJS typiques (avec Python Flask)

226

Je suis assez nouveau dans toute cette frénésie de framework côté client MV *. Il n'est pas nécessaire que ce soit AngularJS, mais je l'ai choisi car il me semble plus naturel que Knockout, Ember ou Backbone. Quoi qu'il en soit, à quoi ressemble le flux de travail? Les gens commencent-ils par développer une application côté client dans AngularJS, puis y connectent le back-end?

Ou l'inverse en construisant d'abord le back-end dans Django, Flask, Rails, puis en y attachant une application AngularJS? Existe-t-il une «bonne» manière de procéder, ou s'agit-il simplement d'une préférence personnelle au final?

Je ne suis pas sûr non plus de structurer mon projet selon Flask ou AngularJS? pratiques communautaires.

Par exemple, l'application minitwit de Flask est structurée comme suit:

minitwit
|-- minitwit.py
|-- static
   |-- css, js, images, etc...
`-- templates
   |-- html files and base layout

L'application du didacticiel AngularJS est structurée comme suit:

angular-phonecat
|-- app
    `-- css
    `-- img
    `-- js
    `-- lib
    `-- partials
    `-- index.html
|-- scripts
 `-- node.js server and test server files

Je pourrais imaginer une application Flask seule, et il est assez facile de voir une application AngularJS comme ToDo List en elle-même, mais quand il s'agit d'utiliser ces deux technologies, je ne comprends pas comment elles fonctionnent ensemble. Il semble presque que je n'ai pas besoin d'un framework web côté serveur quand vous avez déjà AngularJS, un simple serveur web Python suffira. Dans l'application de tâches AngularJS, par exemple, ils utilisent MongoLab pour parler à la base de données à l'aide de l'API Restful. Il n'était pas nécessaire d'avoir un framework web sur le back-end.

Peut-être que je suis juste terriblement confus, et AngularJS n'est rien de plus qu'une bibliothèque jQuery sophistiquée, donc je devrais utiliser tout comme j'utiliserais jQuery dans mes projets Flask (en supposant que je change la syntaxe du modèle AngularJS en quelque chose qui n'entre pas en conflit avec Jinja2). J'espère que mes questions ont un certain sens. Je travaille principalement sur le back-end et ce framework côté client est un territoire inconnu pour moi.

Sahat Yalkabov
la source

Réponses:

171

Je commencerais par organiser l'application Flask dans la structure standard comme suit:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
|-- templates

Et comme l'a mentionné btford, si vous faites une application Angular, vous voudrez vous concentrer sur l'utilisation de modèles côté client Angular et rester à l'écart des modèles côté serveur. L'utilisation de render_template ('index.html') obligera Flask à interpréter vos modèles angulaires comme des modèles jinja, donc ils ne seront pas rendus correctement. Au lieu de cela, vous voudrez faire ce qui suit:

@app.route("/")
def index():
    return send_file('templates/index.html')

Notez que l'utilisation de send_file () signifie que les fichiers seront mis en cache, donc vous voudrez peut-être utiliser make_response () à la place, au moins pour le développement:

    return make_response(open('templates/index.html').read())

Ensuite, créez la partie AngularJS de votre application, en modifiant la structure de l'application pour qu'elle ressemble à ceci:

app
|-- app.py
|-- static
    |-- css
    |-- img
    |-- js
        |-- app.js, controllers.js, etc.
    |-- lib
        |-- angular
            |-- angular.js, etc.
    |-- partials
|-- templates
    |-- index.html

Assurez-vous que votre index.html inclut AngularJS, ainsi que tout autre fichier:

<script src="static/lib/angular/angular.js"></script>

À ce stade, vous n'avez pas encore construit votre API RESTful, vous pouvez donc demander à vos contrôleurs js de renvoyer des exemples de données prédéfinies (uniquement une configuration temporaire). Lorsque vous êtes prêt, implémentez l'API RESTful et connectez-la à votre application angulaire avec angular-resource.js.

EDIT: J'ai mis en place un modèle d'application qui, bien qu'un peu plus complexe que ce que j'ai décrit ci-dessus, illustre comment on pourrait construire une application avec AngularJS + Flask, avec une communication entre AngularJS et une simple API Flask. Le voici si vous voulez le vérifier: https://github.com/rxl/angular-flask

Ryan
la source
1
Je suis tombé sur ce problème: le contexte du fichier n'a pas été conservé lorsque j'ai tenté de servir le fichier index.html de manière statique. J'ai contourné cela en ajoutant mon fichier statique avec app.root_path. Sinon, c'est assez bien.
Makoto
Pouvez-vous expliquer plus sur "Notez que l'utilisation de send_file () signifie que les fichiers seront mis en cache, donc vous voudrez peut-être utiliser make_response () à la place, au moins pour le développement"? Merci
nam
Comment gérez-vous les builds, comme l'utilisation de grunt avec cette approche?
Saad Farooq
1
@nam, je pense que ce qu'il veut dire, c'est que si vous effectuez de petites modifications dans votre js, etc. pendant le débogage, vous ne verrez pas l'effet dans le navigateur car send_file met en cache les fichiers servis avec un délai d'attente = SEND_FILE_MAX_AGE_DEFAULT. il existe des moyens de remplacer cela, mais il est beaucoup plus simple d'utiliser simplement make_response jusqu'à ce que vous soyez prêt pour le déploiement.
ars-longa-vita-brevis
@SaadFarooq Je ne couvre pas le grognement ici car cela complique un peu les choses. Si vous êtes prêt à utiliser quelque chose comme Grunt, il est logique d'avoir un référentiel distinct pour le code frontal, puis de tout regrouper, de le copier-coller dans le référentiel Flask ou de le pousser vers un CDN et de le référencer depuis index.html.
Ryan
38

Vous pouvez commencer à chaque extrémité.

Vous avez raison, vous n'avez probablement pas besoin d'un framework complet côté serveur avec AngularJS. Il est généralement préférable de servir des fichiers HTML / CSS / JavaScript statiques et de fournir une API RESTful pour le client principal à utiliser. Une chose que vous devriez probablement éviter est de mélanger les modèles côté serveur avec les modèles côté client AngularJS.

Si vous souhaitez utiliser Flask pour servir vos fichiers (peut-être exagéré, mais vous pouvez néanmoins l'utiliser), vous devez copier le contenu de "app" de "angular-phonecat" dans le dossier "statique" de "minitwit".

AngularJS est plus ciblé sur les applications de type AJAX, tandis que flask vous donne la possibilité de faire à la fois les applications Web de style plus ancien et de créer des API RESTful. Il y a des avantages et des inconvénients à chaque approche, donc cela dépend vraiment de ce que vous voulez faire. Si vous me donnez quelques idées, je pourrais peut-être faire d'autres recommandations.

btford
la source
26
+1 - mais je ne dirais pas que Flask est destiné aux applications Web de style ancien - il fournit également tous les assistants dont vous avez besoin pour l'utiliser comme backend d'API Web ;-) Il y a aussi Flask-Restless si vous voulez être capable de générer une API de service JSON pour votre application Web très facilement en utilisant Flask-SQLAlchemy - juste pour info :-)
Sean Vieira
Bon point! Je ne connais pas particulièrement Flask; merci d'avoir fourni une certaine expertise sur le sujet.
btford
3
consultez également notre tutoriel qui montre comment créer des applications crud avec angular et tous les outils que nous fournissons: docs.angularjs.org/tutorial
Igor Minar
2
Pour moi, il semble juste de placer le dossier "app" de "angular-phonecat" dans le dossier statique. Mais je pense que le fichier index.html devrait être placé dans le dossier des modèles de minitwit. Les dossiers css et img doivent être déplacés vers "statiques".
Nezo
22

Cette vidéo officielle Jetbrains PyCharm par John Lindquist (angular.js et jetbrains gourou) est un bon point de départ car elle montre l'interaction du webservice, de la base de données et d'angular.js dans la fiole.

Il construit un clone pinterest avec flask, sqlalchemy, flask-agité et angular.js en moins de 25 minutes.

Profitez-en: http://www.youtube.com/watch?v=2geC50roans

Bijan
la source
17

edit : Le nouveau guide de style Angular2 suggère une structure similaire, sinon la même, beaucoup plus en détail.

La réponse ci-dessous cible des projets à grande échelle. J'ai passé pas mal de temps à réfléchir et à expérimenter plusieurs approches afin de pouvoir combiner un cadre côté serveur (Flask avec App Engine dans mon cas) pour la fonctionnalité back-end avec un cadre côté client comme Angular. Les deux réponses sont très bonnes, mais je voudrais suggérer une approche légèrement différente qui (dans mon esprit au moins) évolue de manière plus humaine.

Lorsque vous implémentez un exemple TODO, les choses sont assez simples. Lorsque vous commencez à ajouter des fonctionnalités et de petits détails sympas pour l'amélioration de l'expérience utilisateur, il n'est pas difficile de se perdre dans le chaos des styles, du javascript, etc.

Mon application a commencé à devenir assez grande, j'ai donc dû prendre du recul et repenser. Initialement, une approche comme celle suggérée ci-dessus fonctionnerait, en réunissant tous les styles et tous les JavaScript ensemble, mais ce n'est pas modulaire et pas facilement maintenable.

Et si nous organisions le code client par fonctionnalité et non par type de fichier:

app
|-- server
    |-- controllers
        |-- app.py
    |-- models
        |-- model.py
    |-- templates
        |-- index.html
|-- static
    |-- img
    |-- client
        |-- app.js
        |-- main_style.css
        |-- foo_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
        |-- bar_feature
            |-- controller.js
            |-- directive.js
            |-- service.js
            |-- style.css
            |-- html_file.tpl.html
    |-- lib
        |-- jquery.js
        |-- angular.js
        |-- ...

etc.

Si nous le construisons comme ceci, nous pouvons envelopper chacun de nos répertoires dans un module angulaire. Et nous avons divisé nos fichiers de manière agréable afin que nous n'ayons pas à passer par du code non pertinent lorsque nous travaillons avec une fonctionnalité spécifique.

Un exécuteur de tâches comme Grunt correctement configuré, pourra trouver et concaténer et compiler vos fichiers sans trop de tracas.

aux seins nus
la source
1

Une autre option consiste à séparer complètement les deux.

projet
| - serveur
| - client

Les fichiers liés à la fiole vont sous le dossier du serveur et les fichiers liés à angularjs vont sous le dossier client. De cette façon, il sera plus facile de changer le backend ou le front-end. Par exemple, vous souhaiterez peut-être passer de Flask à Django ou AngularJS à ReactJS à l'avenir.

John Kenn
la source
Kevin: Vous voudrez peut-être revoir le lien, comme indiqué sur la page de connexion à Facebook.
RussellB
0

Je pense qu'il est important de déterminer à quelle fin vous voulez faire la plupart de votre traitement de données - front-end ou back-end.
Si elle est frontale, optez pour le flux de travail angulaire, ce qui signifie que votre application de flacon fonctionnera comme plus d'une API où une extension comme flask-restful se terminera.

Mais si comme moi, vous faites le plus de travail sur le backend, alors allez avec la structure du flacon et ne branchez que angulairement (ou dans mon cas vue.js) pour construire le front end (quand c'est nécessaire)

Kudehinbu Oluwaponle
la source