Как я построил проект на Django, Django REST Framework, Angular 1.1.x и Webpack - Блог ITVDN
ITVDN: курсы программирования
Видеокурсы по
программированию

    Выбери свою IT специальность

    Подписка

    Выбери свою IT специальность

    Подписка

      Как я построил проект на Django, Django REST Framework, Angular 1.1.x и Webpack

      advertisement advertisement

      Моя идея состояла в том, чтобы построить простой репликабельный проект на Angular с бэкэндом на Django. Я искал и не смог найти нужных решений, пришлось во всем разбираться самому. В итоге я разобрался и решил сам написать гайд для всех, кого может заинтересовать данная проблема. 
      Данная статья поможет вам построить простое приложение Angular с бэкэндом на Django, организованного с помощью Webpack.


      Проблема

      Я хочу настроить проект на Angular 1.1.x и скормить ему данные с сервера Django. Мне бы хотелось использовать Django REST Framework (DRF), чтобы пострить RESTful API. Я также хочу сбандлить JS ассеты. Сейчас я собираюсь запустить сайт на одном сервере.

      Предварительные требования

      • Python 2.x

      • Django 1.9.x

      • npm 2.15.8+

      • Webpack 1.13.x (sudo npm i -g webpack)

      • ESLint 2.13.1+ (sudo npm i -g eslint)

      • NodeJS 4.4.7+

      Содержание

      1. Скаффолдинг проекта. Создайте свои начальные директории.

      2. Скаффолдинг проекта на Django.

      3. Настрока переменных среды, нужных для запуска сервера Django.

      4. Установка Django REST Framework и настройка Django с использованием переменных среды.

      5. Создание API.

      6. Запуск Django сервера с использованием dev settings.

      7. Инициализация npm-пакета и установка front-end JS зависимостей.

      8. Создание Angular entry-point и загрузка начальных зависимостей.

      9. Настройка Webpack'а.

      10. Дайте команду Django загрузить приложение.

      11. Создайте шаблон базы приложения Angular.

      12. Напишите компонент home.

      13. Напишите Angular роуты, ведущие к вашему компоненту home и странице 404.

      14. Добавьте директивы ангуляр-маршрутизатора к шаблону входной точки приложения.

      15. Проверьте ваше REST API в приложении Angular.  Шпаргалка.

      Итак, начнем!

      0. Настройте среду для Python.

      mkvirtualenv mysite  

      1. Скаффолдинг проекта на Django. Создайте начальные директории.

      Мы хотим сфокусироваться на модулярности в ходе разработки. Следовательно, существует множество директорий в конечном итоге использования. Мы хотим, чтобы наше дерево изначально выглядело так:

      mysite  
      ├── backend
      │   ├── docs
      │   ├── requirements
      └── frontend
          ├── app
          │   ├── components
          │   └── shared
          ├── assets
          │   ├── css
          │   ├── img
          │   ├── js
          │   └── libs
          ├── config
          ├── dist
              └── js

       Сделайте следующее:

      mkdir mysite && cd mysite  
      mkdir -p backend/docs/ backend/requirements/ \  
               frontend/app/shared/ \
               frontend/app/components/ \
               frontend/config \
               frontend/assets/img/ frontend/assets/css/ \
               frontend/assets/js/ frontend/assets/libs/ \
               frontend/dist/js/

       *Примечание: Структура этого проекта была навеяна опытом с несколькими другими проектами. Я считаю эту организацию идеальной, но вам не обязательно ей следовать. Но, пока вы читаете этот гайд, вы должны придерживаться этой структуры.

      2. Скаффолдинг проекта на Django.

      В директории backend/ создайте Django проект:

      python django-admin.py startproject mysite  

       Также создайте requirements.txt:

      pip freeze > requirements/requirements.txt 

      В директории (вашего проекта) backend/mysite/ произведите скаффолдинг директории, той, где будет жить ваше API:

      mkdir -p applications/api/v1/  
      touch applications/__init__.py applications/api/__init__.py \  
              applications/api/v1/__init__.py applications/api/v1/routes.py \
              applications/api/v1/serializers.py applications/api/v1/viewsets.py

      Теперь создайте структуру директории настроек:

      mkdir -p configlord/settings/  
      touch configlord/settings/__init__.py \  
              configlord/settings/base.py configlord/settings/dev.py configlord/settings/prod.py \
              configlord/dev.env configlord/prod.en

      3. Настройте переменные окружения, которые нужны для запуска сервера Django.

      На этом этапе я предпочитаю пользоваться django-environ для работы с переменными окружения. Существует множество способов сделать это, но пакет django-environ чрезвычайно упрощает этот процесс, поэтому я использую его во всех своих проектах.

      Установите django-environ:

      pip install django-environ 

       В mysite/dev.env добавьте следующее:

      DATABASE_URL=sqlite:///mysite.db  
      DEBUG=True  
      FRONTEND_ROOT=path/to/mysite/frontend/  
      SECRET_KEY=_some_secret_key 

      Мы собираемся использовать эти переменные среды в наших настройках. Выгода от использования наших переменных окружения в отдельных файлах состоит в основном в том, что такая настройка позволяет облегчить переключение между средами. В нашем случае файл the dev.env является списком переменных, которые мы бы использовали в локальной среде разработки.

      *Примечание: SECRET_KEY можно взять из settings.py, который был сгенерирован django-admin.py startproject.

      4. Установите Django REST Framework и настройте Django, используя переменные среды.

      Установка DRF:

      pip install djangorestframework 

      Наполните settings/base.py  следующим:

      Укажите, где искать переменные окружения.

      import environ
      
      project_root = environ.Path(__file__) - 3  
      env = environ.Env(DEBUG=(bool, False),)  
      CURRENT_ENV = 'dev' # 'dev' is the default environment
      
      # read the .env file associated with the settings that're loaded
      env.read_env('./mysite/{}.env'.format(CURRENT_ENV))

      Установите базу данных. В данном случае мы собираемся использовать встроенные в django-environ настройки SQLite.

      DATABASES = {  
          'default': env.db()
      }

      Установите SECRET_KEY ,а также debug.

      SECRET_KEY = env('SECRET_KEY')  
      DEBUG = env('DEBUG')

      Добавьте DRF в пул приложений, которые Django должен использовать.

      # Application definition
      INSTALLED_APPS = [
      
          ...
      
          # Django Packages
          'rest_framework',
      ]

      Ссылки будут «жить» в специальном URL модуле, созданном с помощью базы проекта.

      ROOT_URLCONF = 'mysite.urls'

      Укажите Django, где искать все шаблоны и другие статические ассеты.

      STATIC_URL = '/static/'  
      STATICFILES_FINDERS = [  
          'django.contrib.staticfiles.finders.FileSystemFinder',
          'django.contrib.staticfiles.finders.AppDirectoriesFinder',
      ]
      STATICFILES_DIRS = [  
          env('FRONTEND_ROOT')
      ]
      
      TEMPLATES = [  
          {
              'BACKEND': 'django.template.backends.django.DjangoTemplates',
              'DIRS': [env('FRONTEND_ROOT')],
              'APP_DIRS': True,
              'OPTIONS': {
                  'context_processors': [
                      'django.template.context_processors.debug',
                      'django.template.context_processors.request',
                      'django.contrib.auth.context_processors.auth',
                      'django.contrib.messages.context_processors.messages',
                  ],
              },
          },
      ]

      В соответствии с настройкой TEMPLATES Django должен будет искать шаблоны внутри frontend/ directory. Это то, где Angular приложение будет жить. Мы используем только Django, чтобы обслужить шаблон, внутри которого Angular приложение будет загружаться, которое будет выполнено через entry-point директиву. Если вы не знаете, о чем я, продолжайте чтение... 

      Наполните settings/dev.py:

      from mysite.settings.base import *
      
      
      CURRENT_ENV = 'dev'

      Здесь мы указываем, что этот файл настроек унаследывает настройки из base.py и переопределяет строку CURRENT_ENV, найденную в base.py. Мы говорим: «Используй это значение вместо значения, найденного в наследуемом модуле».

      5. Создайте API.

      Нам нужно нечто, с помощью чего мы сможем протестировать службы Angular, поэтому давайте создадим небольшое API. Этот шаг можно пропустить, но я не советовал бы делать этого. Нам важно знание того, что настройки приложения Angular работают исключительно с точки зрения его потенциала, чтобы облегчить HTTP запросы.

      Сгенерируйте приложение.

      manage.py startapp games 

      Создайте модель в games/models.py.

      class Game(models.model):  
          title = models.CharField(max_length=255)
          description = models.CharField(max_length=750)

      Создайте DRF сериализатор для модели игры в  applications/api/v1/serializers.py.

      from rest_framework.serializers import ModelSerializer  
      from applications.games.models import Game
      
      
      class GameSerializer(ModelSerializer):
      
          class Meta:
              model = Game

      Создайте  DRF viewset для модели в приложениях applications/api/v1/viewsets.py.

      from rest_framework import viewsets  
      from applications.games.models import Game  
      from applications.api.v1.serializers import GameSerializer
      
      
      class GameViewSet(viewsets.ModelViewSet):  
          queryset = Game.objects.all()
          serializer_class = GameSerializer

      В applications/api/v1/routes.py зарегистрируйте роуты, используя DRF's router registration features.

      from rest_framework import routers  
      from applications.api.v1.viewsets import GameViewSet
      
      
      api_router = routers.SimpleRouter()  
      api_router.register('games', GameViewSet) 

      Обозначьте ссылки для зарегистрированного DRF роута внутри mysite/urls.py:

      from django.contrib import admin  
      from django.conf.urls import include, url  
      from applications.api.v1.routes import api_router
      
      urlpatterns = [  
          url(r'^admin/', admin.site.urls),
      
          # API:V1
          url(r'^api/v1/', include(api_router.urls)),
      ]

      6. Запустите сервер Django, используя dev settings.

      manage.py runserver --DJANGO_SETTINGS_MODULE=mysite.settings.dev 

      Впуская DJANGO_SETTINGS_MODULE в runserver, мы «говорим» - работать используя специфические параметры.

      Если все работает, у вас появится возможность открыть localhost:8000/api/v1/games и увидеть ответ от DRF. Если все работает – самое время заняться построением приложения Angular. Если нет – направьте автору проблему. Если вы застряли на этом этапе – оставьте комментарий автору под оригиналом публикации.

      7. Инициализируйте npm-пакет и установите front-end JS зависимости.

      Приложение Angular не будет работать так, как мы хотим, если правильные зависимости не будут установленны. Самое время установить базовые пакеты, которые понадобятся.

      Инициализируйте npm-пакет. Прямо из  frontend/ запустите

      npm init --yes  

      By passing the --yes flag into init, you're telling NPM to generate a package.json using NPM defaults. Otherwise, if you don't pass that in, you'll have to answer questions... Boring.

      Установите dev dependencies. 

      npm install --save-dev eslint eslint-loader

      Установите общие зависимости.

      npm install --save eslint eslint-loader angular angular-resource angular-route json-loader mustache-loader lodash

      Файл package.json file во frontend/ должен выглядеть приблизительно следующим образом:

      {
        "name": "my-app",
        "version": "0.0.1",
        "description": "This is my first angular app.",
        "main": "app.js",
        "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1"
        },
        "keywords": [],
        "author": "",
        "license": "ISC",
        "devDependencies": {
          "eslint": "^3.1.1",
          "eslint-loader": "^1.4.1"
        },
        "dependencies": {
          "angular": "^1.5.8",
          "angular-resource": "^1.5.8",
          "angular-route": "^1.5.8",
          "eslint": "^3.1.1",
          "eslint-loader": "^1.4.1",
          "json-loader": "^0.5.4",
          "lodash": "^4.13.1",
          "mustache-loader": "^0.3.1"
        }
      }

      Здесь то, что мы только что установили:

      eslint – отличный линтер, благодаря которому код JavaScript будет в порядке (последователен).

      eslint-loader – для запуска eslint через Webpack. Чуть позже я объясню концепцию «загрузчиков».

      angular -  MVC фреймворк. Если  вы не знали об этом, стоит подумать о том, чтобы закрыть эту страничку прямо сейчас.

      angular-resource -  (Angular) HTTP библиотека выбора. Это абстракция $http.

      json-loader - загрузчик (снова, используемый Webpack) для распаковки JSON из .json файлов с помощью require() во время работы нашего приложения.

      mustache-loader – загрузчик, который мы будем использовать, чтобы парсить наши mustache шаблоны. Mustache шаблоны – это веселье.

      Я могу спокойно предположить, что вы не знаете, как все эти пакеты заиграют вместе. 

      Не переживайте, братишки.

      8. Создайте entry-point в Angular, объявите начальные зависимости, объявите первоначальные глобальные переменные.

      В frontend/app/app.js добавьте следующее:

      /* Libs */
      require("angular/angular");  
      require("angular-route/angular-route");  
      require("angular-resource/angular-resource");
      
      /* Globals */
      _ = require("lodash");  
      _urlPrefixes = {  
        API: "api/v1/",
        TEMPLATES: "static/app/"
      };
      
      /* Components */
      
      /* App Dependencies */
      angular.module("myApp", [  
        "ngResource",
        "ngRoute",
      ]);
      
      /* Config Vars */
      // @TODO in Step 13.
      
      /* App Config */
      angular.module("myApp").config(routesConfig);

      app.js это то, где Webpack будет искать модули, чтобы бандлить их вместе. Лично я ценю такую организацию и методику вызовов, но такой порядок не обязателен. Существует 6 секций:

      • Libs – главные библиотеки, используемые на протяжении работы Angular приложения;
      • Globals – зарезервированные глобальные переменные, которые мы можем использовать во время работы приложения;
      • Components (Компоненты) – особенные модули проекта;
      • App Dependencies (Зависимости приложения) – объявление входной точки приложения и его зависимостей;
      • Config Vars – переменные, где хранятся настройки, такие как route config;
      • App Config - вводит configs (настройки) в приложение, используя сохраненные из предыдущей секции.

      Для того, чтобы globals работали, вам следует указать ESLint на то, какие из переменных - глобальные.

      В config/eslint.json добавляем следующее:

      {
          "env": {
              "node": true
          },
          "extends": "eslint:recommended",
          "rules": {
              "indent": [
                  "error",
                  2
              ],
              "linebreak-style": [
                  "error",
                  "unix"
              ],
              "quotes": [
                  "error",
                  "double"
              ],
              "semi": [
                  "error",
                  "always"
              ],
              "no-console": 0
          },
          "globals": {
              "_": true,
              "_urlPrefixes": true,
              "angular": true,
              "inject": true,
              "window": true
          },
          "colors": true
      }

      Ниже несколько переменных, о которых мы предупредили ESLint:

      • _ представить lodash.
      • _urlPrefixes – объект, который мы будем использовать в приложении для гиперссылок. Я расскажу об этом позже.
      • angular, чтобы представить AngularJS object driving our entire application.
      • inject, который будет использоваться для ввода зависимостей Angular.
      • window, которая просто представляет объекты окон в JavaScript, является представителем  DOM.

      9. Настройка Webpack.

      Теперь, когда мы выложили большинство наших зависимостей приложения, мы можем построить config file для Webpack. Webpack будет консолидировать все зависимости, а также модули для приложений, которые мы создаем в один файл. В bundle.

      В frontend/webpack.config.js добавляем следующее.

      module.exports = {  
          entry: "./app/app.js",
          output: {
              path: "./dist/js/",
              filename: "bundle.js",
              sourceMapFilename: "bundle.js.map",
          },
      
          watch: true,
      
          // eslint config
          eslint: {
            configFile: './config/eslint.json'
          },
      
          module: {
              preLoaders: [{
                  test: /\.js$/,
                  exclude: /node_modules/,
                  loader: "eslint-loader"
              }],
              loaders: [
                { test: /\.css$/, loader: "style!css" },
                { test: /\.html$/, loader: "mustache-loader" },
                { test: /\.json$/, loader: "json-loader" }]
          },
      
          resolve: {
              extensions: ['', '.js']
          }
      };
      

      Для того, чтобы Webpack бандлил все наши статические зависимости, нам нужно указать ему, где их брать, какие зависимости обрабатывать и как управлять ими до банлинга.

      Давайте посмотрим на то, что указывает Webpack с помощью webpack.config.js:

      Entry - это путь к тому, что Webpack'у нужно для старта бандлинга. Это можеть быть полный путь или путь, относительный тому, где webpack.config.js располагается. В данном случае мы говорим о последнем варианте.

      output -  это объект, содержащий в себе path, который является директорией, в которую связанные зависимости будут помещаться; filename - это название бандла; и, в данном случае, мы решили использовать sourceMapFilename, чтобы обозначить, что наша() source map будет вызван(а).

      watch указывает Webpack следить за изменениями в файле, пока он выполняется. Если это не настроено как true, Webpack прогонит процесс бандлинга единожды и остановится.

      eslint содержит в себе специфические ESLint настройки, используемые eslint-loader.

      module указывает Webpack'у, что делать с модулями, с которыми он работает.

      module.preLoaders «говорит», что делать перед бандлингом. В данном случае мы хотим запустить модули (исключив модули установленные npm) через eslint.

      module.loaders - это то, где указана последовательность загрузчика. В нашем случае мы просто настраиваем test и loader,  где test указывает Webpack’у, какие модули запускать в загрузчике (по соответствию с паттерном regex), и loader говорит Webpack’y, какой загрузчик использовать в модулях, которые соответствуют regex паттерну в test. Каждый загрузчик указан в строке и разделен восклицательным знаком. Ex:  loader!another_loader!yet_another_loader

      module.preLoaders указывает, какие preLoaders'у запускать модули. Используемые настройки такие же точно, какие мы использовали в module.loaders.

      Но, Грег, какая  разница между preLoaders и loaders? Я рад, что ты спросил, мой дорогой друг!!

      A loader указывает Webpack'у, как бандлить требуемые файлы. Loader смотрит на модуль и говорт: «Эй, так как вы упаковываете это в один файл как строку – это то, как оно должно быть преобразованно для bundle'а».

      A preLoader обрабатывает код перед loaders, например, чтобы слинтить JavaScript модули.

      A postLoader является плагином Webpack'а, который обрабатывает код после бандинга. Мы не специфицировали ни один  postLoader ради простоты.

      10. Укажите Django загрузить приложение.

      Прямо сейчас все, что нужно сделать – указать Webpack’у что создавать, как создавать и что должно быть создано. (На данном этапе я бы очень удивился, если вы попробуете запустить его и он заработает без ошибок. Если так и есть, я чертов мужик.)

      Так как Django использует свой собственный URL процессор в нашем приложении, мы можем быть рады тому, как любезно Django управляет всем тем, что введено в строку браузера пользователя. Как бы то ни было, мы бандлим одностраничное приложение, используя абсолютно другой фреймворк, и хотим, чтобы у приложения был полный контроль над тем, что пользователь вводит. Все, что нам нужно  – обслуживать одну страничку, в которой работает SPA. Следовательно...

      В backend/mysite/mysite/urls.py добавляем в список urlpatterns следующее:

      # Web App Entry
      url(r'^$', TemplateView.as_view(template_name="app/index.html"), name='index'), 

      Это значит, что когда пользователь открывает mysite.com/env('FRONTEND_ROOT') + app/index.html будет находить STATICFILES_FINDERS  в порядке рендера HTML шаблона.

      11. Создайте шаблон базы приложения Angular.

      frontend/app/components/app/index.html шаблон должен выглядеть как обычный шаблон Django.

      В frontend/app/index.html добавляем следующее:

      {% load staticfiles %}
        
      <html ng-app="myApp">  
        <head>
          <title>My Sitetitle>
          <script src="{% static 'dist/js/bundle.js' %}">script>
        head>
        <body>
        body>
      html> 

      В таком случае вам удастся запустить Webpack. Если вы запустите Django сервер и откроете localhost:8000,вы увидите пустую страничку. Если нет – дайте знать автору.

      12. Напишите home component.

      Давайте напишем наш первый компонент. Он отобразит текст на страничке, пока пользователь открывает localhost:8000.

      Создайте директорию для компонента и базовые файлы. В frontend/app/components/:

      mkdir home && touch home/home-controller.js home/home.js home/home.html

      В frontend/app/components/home/home.html добавляем следующее:

      <div ng-controller="HomeController as ctrl">  
          <div>
              <h1>Home!h1>
          div>
      div> 

      Теперь добавим следующее в  frontend/app/components/home/home-controller.js:

      function HomeController() {  
        var that = this;
        that.foo = "Foo!";
        console.log(that); // should print out the controller object
      }
      
      angular.module("Home")  
        .controller("HomeController", [
          HomeController
        ])
      

      Определение модуля Angular должно быть объявлено в home.js:

      angular.module("Home", []);
      
      require("./home-controller");  

      Теперь мы можем сослаться на "Home" в области зависимости определения модуля. Давайте сделаем это!

      В app/app.js добавьте следующее:

      /* Components */
      require("./components/home/home");
      
      /* App Dependencies */
      angular.module("myApp", [  
        "Home", // this is our component
        "ngResource",
        "ngRoute"
      ]);

      13. Пропишите пути Angular'а, ведущие к home component и страничке 404.

      Нам нужно настроить первый путь. Когда пользователь попадает на localhost:8000, Angular должен взять контроль над загрузкой отрендеренного шаблона. Чтобы сделать это, нам потребуется использовать angular-router.

      В frontend/app/routes.js пишем следующее:

      function routesConfig($routeProvider) {  
        $routeProvider
          .when("/", {
            templateUrl: _urlPrefixes.TEMPLATES + "components/home/home.html",
            label: "Home"
          })
          .otherwise({
            templateUrl: _urlPrefixes.TEMPLATES + "404.html"
          });
      }
      
      routesConfig.$inject = ["$routeProvider"];
      
      module.exports = routesConfig; 

      Если мы не добавим _urlPrefixes.TEMPLATES, angular-router предположит, что components/home/home.html является действительной ссылкой, которую узнает сервер. Так как STATIC_URL в настройках предполагает неправильную работу localhost:8000/components/home/home.html.

      Также, если вы еще не заметили, вы увидите otherwise({...})  в коде роутов. Это то, как будут реализованы страницы 404.

      В frontend/app/404.html добавляем следующее:

      <h1>NOT FOUNDh1> 

      И в завершении  добавляем frontend/app/app.js:

      /* Config Vars */
      var routesConfig = require("./routes");  

      14. Добавьте директивы angular-router к шаблону точки входа приложения.

      А теперь нам нужно указать Angular, где будет происходить переключение отображаемого, когда пользователь пользуется навигацией. Чтобы сделать это, мы используем всю силу angular-router.

      В тэг  

       в frontend/app/index.html добавляем:

      <base href="/">  

      Теперь в тэг 

      добавляем:

      <div ng-view>div>

      Ваш index.html теперь должен выглядеть так:

      {% load staticfiles %}
        
      <html ng-app="myApp">  
        <head>
          <title>My Sitetitle>
            <script src="{% static 'dist/js/bundle.js' %}" >script>
            <base href="/">
        head>
        <body>
          <div>
            <div ng-view>div>
          div>
        body>
      html>  

      Запустите Webpack. Откройте localhost:8000. Вы должны увидеть, что произошло в home/home.html. (Если ничего, отправьте эти данные автору J ).

      15. Проверьте REST API в приложении Angular.

      Если все сделано, у вас появится возможность написать angular службы для Django API. Давайте создадим небольшой компонент, чтобы увидеть, можем ли мы это сделать. Этот компонент должен перечислять игры. Я предполагаю, что вы уже заполнили базы данных, следовательно запрос HTTP к localhost:8000/api/v1/games вернет список игр.

      Создайте скаффолд компонент в frontend/app/components/:

      mkdir -p game/list/ && touch game/list/game-list-controller.js game/list/game-list-controller_test.js game/game-service.js game/game.js game/game.html  

      Этот компонент будет перечислять игры.

      Этот компонент должен перечислять игры. Я предполагаю, что вы уже заполнили базы данных, следовательно запрос HTTP к localhost:8000/api/v1/games вернет список игр.

      В game/game-service.js:

      function GameService($resource) {  
        /**
         * @name GameService
         *
         * @description
         * A service providing game data.
         */
      
        var that = this;
      
        /**
         * A resource for retrieving game data.
         */
        that.GameResource = $resource(_urlPrefixes.API + "games/:game_id/");
      
        /**
         * A convenience method for retrieving Game objects.
         * Retrieval is done via a GET request to the ../games/ endpoint.
         * @param {object} params - the query string object used for a GET request to ../games/ endpoint
         * @returns {object} $promise - a promise containing game-related data
         */
        that.getGames = function(params) {
          return that.GameResource.query(params).$promise;
        };
      }
      
      angular.module("Game")  
        .service("GameService", ["$resource", GameService]);

      Обратите внимание на ссылку $resource, которую мы используем для того, чтобы настроить механизмы HTTP в нашей службе.

      В game/list/game-list-controller.js:

      function GameListController(GameService) {  
        var that = this;
      
        /* Stored game objects. */
        that.games = [];
      
        /**
         * Initialize the game list controller.
         */
        that.init = function() {
          return GameService.getGames().then(function(games) {
            that.games = games;
          });
        };
      }
      
      angular.module("Game")  
        .controller("GameListController", [
          "GameService",
          GameListController
        ]);

      В game/game.html:

      <div ng-controller="GameListController as ctrl" ng-init="ctrl.init()">  
          <div>
              <h1>Gamesh1>
              
              <ul>
                <li ng-repeat="game in ctrl.games">{{ game.title }}li>
              ul>
          div>
      div> 

      В game/game.js:

      angular.module("Game", []);
      
      require("./list/game-list-controller");  
      require("./game-service");  

      Затем обратимся к компоненту в app.js:

      /* Components */
      require("./components/game/game");
      
      /* App Dependencies */
      angular.module("myApp", [  
        "Home",
        "Game",
        "ngResource",
        "ngRoute"
      ]);

      В конце концов, мы собираемся настроить роуты для списка игр, поэтому в frontend/app/routes.js добавьте следующее в объект $routeProvider:

       .when("/game", {
            templateUrl: _urlPrefixes.TEMPLATES + "components/game/list/game-list.html",
            label: "Games"
          })

      Запустите Webpack снова. Все должно верно скомпилироваться. Если нет – дайте знать автору.

      Откройте localhost:8000/#/games. Вы увидите список игр.

      Сделано!

      Это все.

      Сомнения/Мысли

      Но есть некоторые сомнения:

      Глобальные переменные могут конкретно подставить вас, если вы не знаете, как с ними работать. Их локальное поведение не гарантирует того же на продакшене. Насколько я помню, их можно заставить работать, если правильно описан метод. Ваше приложение на Angular тесно связанно с Django. Поэтому ваше приложение не будет просто слиянием back- и фронтенда. Если ваш Django-RIP давно устарел, значит поменялись и маршруты, следовательно сконфигурируете ваш бэкенд согласно тому, как должны вести себя статические файлы. Так же вам будет необходимо заменить index.html с точкой входа Angular. Маленькие проекты не дадут вам особо попотеть, а вот большие явно заставят понервничать. Совет: единственное место, где должны сопрягаться приложение на Angular и Django сервер - это одна точка входа.

      Деплоймент должен быть выполнен так же, как любой обычный деплоймент приложения.

      Это все. Если у вас есть какие-либо вопросы и вы испытываете трудности, пожалуйста, оставьте их в комментариях в исходной статье!

      Чит!

      Автор пообещал выложить на гитхабе репозиторий со всем кодом.

      Оригинальная статья на английском языке. 

      КОММЕНТАРИИ И ОБСУЖДЕНИЯ
      advertisement advertisement

      Покупай подпискус доступом ко всем курсам и сервисам

      Библиотека современных IT знаний в удобном формате

      Выбирай свой вариант подписки в зависимости от задач, стоящих перед тобой. Но если нужно пройти полное обучение с нуля до уровня специалиста, то лучше выбирать Базовый или Премиум. А для того чтобы изучить 2-3 новые технологии, или повторить знания, готовясь к собеседованию, подойдет Пакет Стартовый.

      Стартовый
      • Все видеокурсы на 3 месяца
      • Тестирование по 10 курсам
      • Проверка 5 домашних заданий
      • Консультация с тренером 30 мин
      59.99 $
      Оформить подписку
      Весенний
      • Все видеокурсы на 15 месяцев
      • Тестирование по 24 курсам
      • Проверка 20 домашних заданий
      • Консультация с тренером 120 мин
      90.00 $
      219.99 $
      Оформить подписку
      Акция
      Базовый
      • Все видеокурсы на 6 месяцев
      • Тестирование по 16 курсам
      • Проверка 10 домашних заданий
      • Консультация с тренером 60 мин
      72.00 $
      89.99 $
      Оформить подписку
      Акция
      Notification success
      Мы используем cookie-файлы, чтобы сделать взаимодействие с нашими веб-сайтами и услугами простым и значимым.