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

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

    Подписка
    РУС
    • РУС
    • УКР
    Arrow
    27 марта состоится вебинар «Подготовка к собеседованию по PHP» Подробности и регистрация
    Arrow

    Как я построил проект на 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 $
    Оформить подписку
    Акция
    Премиум
    • Все видеокурсы на 1 год
    • Тестирование по 24 курсам
    • Проверка 20 домашних заданий
    • Консультация с тренером 120 мин
    169.99 $
    Оформить подписку
    Notification success