Як я побудував проект на 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 $
      Придбати
      Базовий
      • Усі відеокурси на 6 місяців
      • Тестування з 16 курсів
      • Перевірка 10 домашніх завдань
      • Консультація з тренером 60 хв
      89.99 $
      Придбати
      Преміум
      • Усі відеокурси на 1 рік
      • Тестування з 24 курсів
      • Перевірка 20 домашніх завдань
      • Консультація з тренером 120 хв
      169.99 $
      Придбати
      Notification success
      Ми використовуємо cookie-файли, щоб зробити взаємодію з нашими веб-сайтами та послугами простою та значущою.