ДАВАЙТЕ построим веб-приложение на YEOMAN

Алло! Алло! В данной 1-часовой кодовой лаборатории, вы построите полнофункциональное веб-приложение с нуля, с помощью Yeoman. Вы также будете использовать функции из Grunt и Bower. Пример приложения будет записан в AngularJS.

Описание: http://yeoman.io/static/yeoman-008.1c21c31597.png

Еще не встречали Yeoman?  Начните отсюда с введения »

Не знаете ни одного AngularJS? Это нормально, мы расскажем вам о нем. Однако мы предполагаем, что у вас есть предыдущий опыт JavaScript.

Сборка этого образца приложения с Yeoman

Образец веб-приложения, которое вы будете строить сегодня будет Todo приложение. Вы сможете добавлять todo-сы, удалять todo-сы, организовать свой todo методом перетаскивания и сохранять todo-сы в автономном режиме.

Finished todo app

Что нового в этой кодовой лаборатории?

Мы будем строить вышеуказанное приложение Todo с нуля. Каждый шаг основывается на предыдущем так что идите через все этапы один за другим.

·           Шаг 1:  Настройте вашу среду разработки »

·           Шаг 2:  Установите YEOMAN генератор »

·           Шаг 3:  Используйте генератор для постройки вашего приложения »

·           Шаг 4:  Просмотрите сгенерированную с Yeoman помощью структуру каталогов приложения »

·           Шаг 5:  Предварительный просмотр приложения в браузере »

·           Шаг 6:  Начните писать свое приложение AngularJS »

·           Шаг 7:  Используйте Bower для установки пакетов »

·                         Шаг 8: Tест с Karma и Jasmine »

·           Шаг 9:  Сделайте todo-сы постоянными с помощью локального хранилища »

·           Шаг 10:  Подготовьтесь к работе »

·           Нравится, что вы видите? Yeoman может больше »

Это займет около 60 минут, чтобы завершить эту кодовую лабораторию. В конце концов, вы будете иметь шикарное приложение Todo, и ваш компьютер будет настроен, чтобы построить еще более потрясающие веб-приложения в будущем.

Просмотр окончательного исходного кода

Готовое приложение можно найти на bit.ly/yoangular. В случае, если вы застряли, вот конкретные файлы, которые мы будем редактировать в папке angular-localStorage-todos > app:

·         index.html

·         визуализация > main.html

·         скрипты > app.js

·         скрипты > контроллеры > main.js

Примечание: Чтобы запустить приложение после загрузки исходного кода, запустите npm install с последующим bower install в каталоге angular-localStorage-todos. Затем вы можете запустить grunt serve


Наслаждаетесь кодированием в облаке? Не имеете права администратора на компьютере? Попробуйте кодовую лабораторию в Codio Web IDE.

Чтобы сохранить свою среду Yeoman настроек на локальном компьютере для дальнейшего развития, перейдите к шагу 1.

Давайте начнем с Шага 1 »

ВСТРЕЧАЙТЕ YEOMAN

Yeoman это человек в шляпе с трюками в рукаве.

С помощью всего лишь команды или двух, Yeoman может написать шаблонный код для всего вашего веб-приложения или отдельных кусочков, как контроллеры и модели. Yeoman может запустить веб-сервер просмотра и смотреть ваши файлы для редактирования, чтобы оставить изменения перезарядки и компиляцию Sass. Yeoman также может работать с вашими модульными тестами, минимизировать и объединять свой код, оптимизировать изображения, плюс еще много всего!

 

  • yo является инструментом подмостки, который предлагает экосистему рамочных конкретных "строительных лесов", называемых генераторами, которые могут быть использованы для выполнения некоторых трудоемких задач, упомянутых ранее.

Yeoman также работает с другими инструментами для улучшения производительности:

·         grunt используется для построения, просмотра и тестировки вашего проекта, благодаря помощи из задач, курируемых командой Yeoman и grunt-contrib.

·         gulp является альтернативой Grunt JS, что выступает за код вместо конфигурации.

·         bower используется для управления зависимостями, так что вам больше не нужно вручную загружать ваши интерфейсные библиотеки.

Вы можете установить генераторы Yeoman используя команду npm и существует более 500 генераторов, доступных сейчас, многие из которых были написаны с открытым исходным кодом сообщества. Популярные генераторы включают generator-angulargenerator-backbone, и generator-polymer.

Зачем использовать Yeoman?

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

« Назад к обзору

 

ШАГ 1: настройте DEV СРЕДУ

 

Большинство ваших взаимодействий с Yeoman будет через командную строку. Запуск команд в терминальном приложении, если вы на Mac, в вашем командном интерпретаторе в Linux, или cmder (предпочтительно) / PowerShell / cmd.exe если у вас Windows.

Установка необходимых компонентов

Перед установкой Yeoman, вам понадобится следующее:

·  Node.js v0.10.x+

·  npm (который идет в комплекте с узлом) v2.1.0+

·  git

Вы можете проверить, установлены ли у вас Node и npm, набрав:

$ node --version && npm --version

Если вам необходимо обновить или установить Node, самый простой способ состоит в использовании установки для вашей платформы. Загрузите .msi для Windows или .pkg для Mac с вебсайта NodeJS.

Пакетный менеджер npm поставляется вместе с Node, хотя вам, возможно, потребуется обновить его. Некоторые версии Node поставляться с довольно старыми версиями npm. Вы можете обновить npm с помощью этой команды:

$ npm install --global npm@latest

Вы можете проверить, установлен ли у вас Git, набрав:

$ git --version

Если у вас нет Git, возьмите инсталляторы из вебсайта git.

Установите набор инструментов Yeoman

После того как вы установили Node, установите набор инструментов Yeoman:

$ npm install --global yo bower grunt-cli

Ошибки?

Если вы видите ошибки разрешения или доступа, такие как EPERM или EACCESS, не используйте sudo как обходной путь. Вы можете проконсультироваться с этим руководством для более надежного решения.

Подтвердите установку

Это хорошая идея, чтобы проверить, что все установлено, как ожидалось, запустив часто используемые Yeoman-команды типа yobower, и grunt с флагом --version как следующий:

$ yo --version && bower --version && grunt --version

Запуск того, что выше, должен вывесли три отдельных номера версий:

·         Yeoman

·         Bower

  • Grunt CLI (интерфейс командной строки для Grunt)

Версии инструментов CLI, с которыми работает эта кодовая лаборатория

Технология быстро меняется! Этот учебник был протестирован с Yeoman 1.4.6Bower 1.4.1, и grunt-cli v0.1.13. Если вы имеете дело с более новой версией, мы хотели бы услышать об этом. Пожалуйста, откройте тему на нашем трекере.

« Назад к обзору или К следующему шагу »

ШАГ 2: Установка YEOMAN ГЕНЕРАТОРА

В традиционном рабочем процессе веб-разработки, вам нужно будет тратить много времени на создание стандартного кода для вашего веб-приложения, загрузив зависимости, и вручную создавать структуру веб-папки. Yeoman генераторы, на помощь! Давайте установим генератор для проектов AngularJS.

Установите AngularJS генератор

Вы можете установить генераторы Yeoman используя команду npm и есть еще более 1000+ генераторов доступных сейчас, многие из которых были написаны с открытым исходным кодом сообщества.

Установите генератор-angular и генератор-karma с помощью этой команды:

$ npm install --global generator-angular@0.11.1 generator-karma

Это приведет к запуску установки узла пакетов, необходимых для генератора. Использование @0.12.1 будет запрашивать конкретную версию генератора.

Ошибки?

Если вы видите ошибки разрешения или доступа, такие как EPERM или EACCESS, не используйте sudo как обходной путь. Вы можете проконсультироваться с этим руководством для более надежного решения.


Наряду с использованием npm install напрямую, вы можете искать генераторы через интерактивное меню Yeoman. Запуститеyo и выберите Install a generator для поиска опубликованных генераторов.

« назад к обзору or перейти на следующий шаг »

ШАГ 3: Используйте генератор для постройки вашего приложения

Мы использовали слово "подмостки" несколько раз, но вы можете не знать, что это значит. "Строительные леса", в Yeoman- смысле этого слова, означает создания файлов для вашего веб-приложения на основе ваших конкретных запросов конфигурации. На этом этапе, вы увидите, как Yeoman может генерировать файлы специально для угловых приложений - с вариантами использования других внешних библиотек как SASS и Twitter Bootstrap - с минимальными усилиями.

Создайте папку проекта

Создайте папку mytodo для всей вашей работы в кодовой лаборатории:

$ mkdir mytodo && cd mytodo

Эта папка, где генератор разместит «подмосточные» файлы проекта.

В качестве дополнительного бонуса, генератор Angular будет динамически использовать имя папки, чтобы сделать пространство имен для вашего приложения. Например, mytodo станет angular.module('mytodoApp', []). Поэтому убедитесь, что у вас нет ни одного typo в mytodo , прежде чем приступить к следующему шагу.

Генераторы доступа через меню Yeoman

Запустите yo снова, чтобы увидеть ваши генераторы:

$ yo

Если у вас установлено несколько генераторов, вы будете иметь возможность интерактивно выбирать из них. Выделите Запустить генератор Angular. Нажмите Enter, чтобы запустить генератор.

Описание: http://yeoman.io/static/image_7.77d3e1c6c8.png

Используйте генераторы напрямую

В ходе вашего более подробного знакомства с yo, вы можете запустить генераторы непосредственно без использования интерактивного меню, например, так:

$ yo angular

 

Настройка генератора

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

Генератор AngularJS предоставляет варианты использования Sass (с Compass) и включает Twitter Bootstrap. Для этой кодовой лаборатории, мы не будем использовать Sass но будем использовать Bootstrap. Введите n затем y соответственно этим вариантам.

Описание: http://yeoman.io/static/image_8.f700938136.png

Далее, вам будет предложено выбрать, какие угловые модули вы хотели бы включить, а именно:

Описание: http://yeoman.io/static/image_9.0e2b0a8bc2.png

Угловые модули представляют собой автономные JavaScript файлы с полезной функциональностью. Например, модуль ngResource (angular-resource.js) обеспечивает поддержку взаимодействия с RESTful услугами.

Можно выбрать параметры с помощью клавиши пробела.

Давайте разберемся с параметрами по умолчанию. (Так что если вы игрались с клавишей пробела, убедитесь, что все модули выбранные совпадают с приведенным выше скриншотом.)

Hажмите enter и следите за происходящей магией.

Yeoman автоматически выстраивает ваше приложение, захватывает ваши зависимости, и тянет через несколько полезных задач Grunt для рабочего процесса. Через несколько минут мы должны быть готовы перейти на следующий шаг.

Ошибки?

Если вы видите conflict package.json , это временная ошибка. Нажмите у, а затем enter, чтобы продолжить.

Описание: http://yeoman.io/static/conflict.e63509e7bc.png


« назад к обзору или к следующему шагу »

шаг 4: проаерка приложений, генерируемых YEOMAN

Открывайте каталог mytodo чтобы взглянуть на то, что было на самом деле построено. Это будет выглядеть следующим образом:

В mytodo, у нас:

app: родительский каталог для нашего веб-приложения

  • index.html: базовый html файл для нашего Angular-приложения
  • 404.htmlfavicon.ico, и robots.txt: часто используемые веб-файлы, так что вы не должны создавать их самостоятельно

·       scripts: наши собственные JS файлы

o   app.js: наш основной код приложения Angular

o    controllers: наши Angular-контроллеры

·      styles: наши CSS файлы

·       views: место для наших Angular-шаблонов

bower_componentsbower.json: наши зависимости JavaScript/web, установленные с помощью Bower

Gruntfile.jspackage.json,, и node_modules: конфигурация и зависимости требующиеся нашими задачами Grunt

test: построенный исполнитель тестов и модульные тесты для проекта, в том числе шаблонные тесты для наших контроллеров.

« назад к обзору или к следующему шагу »

ШАГ 5: Предварительный просмотр вашего приложения в браузере

Для предварительного просмотра веб-приложения в вашем любимом браузере, вы не должны делать ничего особенного, чтобы настроить локальный веб-сервер на своем компьютере - это часть Yeoman.

Запуск сервера

Запустите Grunt задачу для создания локального сервера http на основе Node на localhost:9000 (или 127.0.0.1:9000 для некоторых конфигураций) набрав:

$ grunt serve

 

Ваш веб-браузер запустит ваше новое построенное приложение в новой вкладке:

Описание: http://yeoman.io/static/image_12.792ec3c414.png

Остановите сервер

Если вам когда-нибудь понадобится остановить сервер, используйте команду на клавиатуре Ctrl+C, чтоб остановить ваш текущий процесс CLI.

Примечание: у вас не может работать более одного сервера http на одном и том же порту (по умолчанию 9000).

Наблюдайте за своими файлами

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

Живая перезагрузка становится доступна в приложении с помощью набора задач Grunt настроенного в Gruntfile.js; это отслеживает изменения файлах и автоматически перезагружает их при обнаружении изменения.

Ниже мы редактируем main.html в каталоге просмотры. Благодаря LiveReload мы переходим от этого:

Описание: http://yeoman.io/static/image_13.8ca9fce190.png

К этому мгновенно:

Описание: http://yeoman.io/static/image_14.a90a8c0d3e.png

« назад к обзору или к следующему шагу »

ШАГ 6: приступаем к написанию приложения ANGULARJS

Файлы, которые вы видите в веб-браузере можно найти в подпапке app вашего каталога mytodo. Все инструкции в данном разделе предполагают, что вы редактируете файлы в этой папке приложения. Если вы не уверены в каких-либо изменениях, которые вам следует делать, обратитесь к конечному исходному коду.

Создание нового шаблона, чтобы показать список задач

Oткройте views/main.html.

Чтобы начать с чистого листа, удалите все из файла main.html за исключением div с классом "jumbotron". Замените "jumbotron" именем класса "container".

Вот что у вас должно получиться сейчас в main.html:

<div class="container">
</div>

Oткройте scripts/controllers/main.js.

Modify this boilerplate Angular Controller to contain a list of todos вместо awesomeThings:

'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function () {
    .todos = ['Item 1', 'Item 2', 'Item 3'];
  });

Затем измените наш вид (main.html) для вывода наших деталей todos как в текстовых полей HTML input:

<div class="container">
  <h2>My todos</h2>
  <p class="form-group" ng-repeat="todo in todos">
    <input type="text" ng-model="todo" class="form-control">
  </p>
</div>

Атрибут  ng-repeatна теге параграфа это Angular директива, которая создает экземпляр шаблона один раз за единицу из коллекции.

В нашем случае, представьте, что этот пункта элемент и его содержание превращается в виртуальный штамп путем добавления атрибута ng-repeat. Для каждого элемента массива todos, Angular будет искоренять новый экземпляр HTML блока <p><input></p>.

Атрибут ng-model является еще одной Angular директивой, которая работает с input, select, textarea и пользовательскими директивами для создания двусторонней совокупности данных. В нашем примере, это заполняет текстовое поле input значением из текущего todo в петле ng-repeat.

Давайте посмотрим на ng-repeat и ng-model в действии в браузере. При сохранении, ваше приложение должно выглядеть следующим образом:

Описание: http://yeoman.io/static/image_15.8de60237f9.png

Вручную обновите .todos четвертым todo понятием:

.todos = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];

С живой перезагрузкой, вы должны увидеть новый пункт todo, который появился в списке.

Вручную удалите четвертый пункт и смотрите, как он исчезнет из списка.

Добавьте todo

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

Измените main.html добавив элемент form между <h2> и <p> из предыдущей секции. Ваш main.html сейчас должен выглядеть так:

<div class="container">
  <h2>My todos</h2>

  <!-- Todos input -->
  <form role="form" ng-submit="addTodo()">
    <div class="row">
      <div class="input-group">
        <input type="text" ng-model="todo" placeholder="What needs to be done?" class="form-control">
        <span class="input-group-btn">
          <input type="submit" class="btn btn-primary" value="Add">
        </span>
      </div>
    </div>
  </form>

    <!-- Todos list -->
    <p class="form-group" ng-repeat="todo in todos">
      <input type="text" ng-model="todo" class="form-control">
    </p>
</div>

Это добавляет форму HTML с кнопкой submit в начало страницы. Оно использует другую директиву Angular, ng-submit до которого мы доберемся следом. Вернитесь в ваш браузер и пользовательский интерфейс должен выглядеть примерно так:

Если вы нажмете сейчас Add, ничего не произойдет - давайте изменим это.

ng-submit связывает Angular выражение c onsubmit событием формы. Если никакие атрибуты действия не применяются к форме, оно также предотвращает поведение браузера по умолчанию. В нашем примере мы добавили угловое выражение addTodo().

Следующая функция addTodo() подталкивает новые пункты todo к имеющемуся элементов массиву списка задач, а затем очищает поле ввода текста:

.addTodo = function () {
  .todos.push(.todo);
  .todo = '';
};

Измените main.js добавив функцию addTodo() в рамках определения контроллера MainCtrl. Ваш полный контроллер должен выглядеть следующим образом:

'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function () {
    .todos = ['Item 1', 'Item 2', 'Item 3'];
    .addTodo = function () {
      .todos.push(.todo);
      .todo = '';
    };
  });

Примечание: Если вы столкнулись с ошибками пылеобразования в окне командной строки, это может быть связано с предостережениями отступа, выброшенными из jshint. Это только предупреждения, поэтому ваше todo приложение будет продолжать работать. Однако, стоит взглянуть на предложения, сделанные jshint и скорректировать свой код соответственно для чистоты и читабельности.

Откройте приложение в браузере снова. Введите текст в поле ввода для нового элемента todo и нажмите Add. Оно будет немедленно отражено в вашем списке дел!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Примечание: При вводе в более чем один пустой пункт todo, или элемент todo с таким же названием, ваше todo приложение неожиданно перестанет работать. :( В качестве забавы поупражняйтесь в свободное время, увеличивая функцию addTodo()на проверку на наличие ошибок.

Удаляем todo

Давайте теперь добавим возможность удалять элемент todo. Нам нужно добавить новую кнопку удалить рядом с каждым пунктом todo.

Возвращаемся к нашему шаблону вида (main.html), добавляем кнопку к существующей директиве ng-repeat. И чтобы убедиться, что наше поле ввода и кнопка удалить легли красиво, измените класс на теге абзаца с "form-group" на "input-group".

Предыдущая разметка:

<!-- Todos list -->
<p class="form-group" ng-repeat="todo in todos">
  <input type="text" ng-model="todo" class="form-control">
</p>

Новая разметка:

<!-- Todos list -->
<p class="input-group" ng-repeat="todo in todos">
  <input type="text" ng-model="todo" class="form-control">
  <span class="input-group-btn">
    <button class="btn btn-danger" ng-click="removeTodo()" aria-label="Remove">X</button>
  </span>
</p>

Взгляните в ваш браузер. Ваше приложение todo выглядит шикарно!

Мы ввели новую директиву Angular выше, ng-click. ng-click позволяет задать пользовательские поведения, когда элемент нажат. В этом случае, мы вызываем removeTodo() и передаем  функции.

Значение  will be the array index of the current todo item within the ng-repeat directive. Например, первый элемент будет иметь индекс массива 0 и removeTodo() будет передано значение 0. Аналогично, последний элемент в списке дел с 5 пунктами будет иметь индекс массива 4 и removeTodo() будет передано значение 4.

Давайте теперь добавим некоторую логику для удаления todo элементов из нашего контроллера. Следующая функция removeTodo()удаляет один todo элемент из массива элементов с помощью метода JavaScript splice() в данном значении :

.removeTodo = function (index) {
  .todos.splice(index, 1);
};

Полный контроллер (main.js) с новой функцией removeTodo() внизу:

'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function () {
    .todos = ['Item 1', 'Item 2', 'Item 3'];
    .addTodo = function () {
      .todos.push(.todo);
      .todo = '';
    };
    .removeTodo = function (index) {
      .todos.splice(index, 1);
    };
  });

Назад в браузер, теперь вы можете нажать кнопку X, чтобы удалить элемент из списка todo. Фантастика!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Одна вещь, которую вы могли заметить, это то, что у нас нет способа сохранения нашего списка задач. Каждый раз, когда мы обновляем страницу, наши детали todo сбрасываются и возвращаются к стандартной схеме в нашем массиве todos, жестко прописаном в main.js. Не волнуйтесь, мы будем это исправлять в  Шаге 10 после того как мы узнаем больше об установке пакетов с Bower в Шаге 7.

« назад к обзору или к следующему шагу »

ШАГ 7: ИСПОЛЬЗОВАНИЕ BOWER для установки пакетов

Давайте добавим некоторый порядок в наш список и сделаем его пригодным. Для этого мы будем использовать Bower для установки модуля AngularUI Sortable, компонент директивы для AngularJS. Если вы продолжаете с последнего шага, вам придется остановить свой сайт в терминале, нажав Ctrl-C или открыть новое окно терминала и перейти в каталог проекта.

Текущий список пакетов

Мы можем проверить, какие пакеты мы уже установили, выполнив команду из каталога проекта myTodo, созданного ранее:

$ bower list

Вы должны увидеть, что у вас уже есть пакеты для angular-cookies, angular-ресурсов, angular-маршрута, плюс другие. Помните, как мы выбрали их как часть Step 3 когда мы настроили наш генератор?

Поиск пакетов

Чтобы убедиться, что пакеты AngularUI доступны, используйте поиск Bower чтоб найти "angular-ui-sortable":

$ bower search angular-ui-sortable

Только один результат для "angular-ui-sortable" потому давайте установим его с jQuery UI так как у нас уже установлен jQuery. Чтоб уберечь вас от поисков, пакетное имя jQuery UI - "jquery-ui".

Установка пакетов

Используйте Bower для установки обоих "angular-ui-sortable" и "jquery-ui":

$ bower install --save angular-ui-sortable
$ bower install --save jquery-ui

Опция --save обновляет файл bower.json с зависимостями от angular-ui-sortable и jquery-ui. Это избавит вас от необходимости вручную добавить его в bower.json.

Установка нескольких пакетов Bower сразу

Если у вас есть несколько пакетов, которые вы хотите установить, вы можете сделать это в одной строке:

$ bower install --save angular-ui-sortable jquery-ui

 

Подтвердите установку

Взгляните на ваш каталог, чтоб bower_components просто проверить, что все есть, как и ожидалось. Вы должны увидеть папки для "jquery-ui" и "angular-ui-sortable" наряду с ранее установленными angular-пакетами:

Сделайте todos сортируемыми

Ссылки на эти вновь установленные зависимости должны быть добавлены в наш файл index.html. Можно вручную добавить файлы - модуль Angular UI Sortable и скрипт JQuery UI - самостоятельно, но Yeoman автоматизирует это для вас!

Закройте свой текущий процесс командной строки с помощью команды Ctrl+C на клавиатуре.

Потом запустите grunt serve снова.

Вы увидите, что секция script внизу index.html автоматически обновилась и включаетjquery-ui/ui/jquery-ui.js и angular-ui-sortable/sortable.js:

<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/angular-touch/angular-touch.js"></script>
<script src="bower_components/jquery-ui/jquery-ui.js"></script>
<script src="bower_components/angular-ui-sortable/sortable.js"></script>
    <!-- endbower -->
<!-- endbuild -->

Для того, чтобы использовать модуль Sortable, мы должны загрузить его в нашем приложении, обновляя наши описания модулей Angular в scripts/app.js. В данный момент это выглядит следующим образом:

angular
  .module('mytodoApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch'
  ])

Добавьте зависимость ui.sortable к списку массивов во втором параметре после 'ngTouch':

angular
  .module('mytodoApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.sortable'
  ])

Наконец, мы должны добавить директиву ui-sortable в качестве обложки div  для ng-repeat в main.html:

<!-- Todos list -->
<div ui-sortable ng-model="todos">
  <p class="input-group" ng-repeat="todo in todos">

Давайте также добавиv некоторые встроенные CSS для того, чтобы показать на перемещение курсора так ясно, что мы можем двигать todo элементы:

<p class="input-group" ng-repeat="todo in todos" style="padding:5px 10px; cursor: move;">

Полная разметка списка задач будет выглядеть так:

<!-- Todos list -->
<div ui-sortable ng-model="todos">
  <p class="input-group" ng-repeat="todo in todos" style="padding:5px 10px; cursor: move;">
    <input type="text" ng-model="todo" class="form-control">
    <span class="input-group-btn">
      <button class="btn btn-danger" ng-click="removeTodo()" aria-label="Remove">X</button>
    </span>
  </p>
</div>

Запустите "grunt serve" снова и снова в браузере, теперь мы можем предварительно заказать наш список:

 

 

 

 

 

 

 

 

 

 

 

 

 

Погладьте себя по спине! Вы только что использовали Yeoman для создания шикарного приложения todo в кратчайшие сроки. Можете ли вы представить создание веб-разработки интерфейсных приложений любым другим способом отныне?

« назад к обзору или к следующему шагу »

ШАГ 8: ТЕСТ с karma и jasmine

Для тех, кто не знаком с Karma, это исполнитель тестов JavaScript, которые являются агностиком среды тестирования. Генератор Angular имеет две включенных среды тестирования: ngScenario и Jasmine. Когда мы запускаем yo angular раньше в этой кодовой лаборатории, генератор строит каталог test в корне папки mytodo, создав файл karma.conf.js, и втащил модули Node для Karma. Мы будем редактировать сценарий Jasmine чтоб описать наши тесты в ближайшее время, но давайте сперва посмотрим, как мы можем запускать тесты.

Запуск модульных тестов

Вернемся к командной строке и убьем наш сервер Grunt с помощью Ctrl+C. Уже есть задание Grunt, построенное в нашем Gruntfile.js для запущеных тестов. Он может быть запущен следующим образом:

$ grunt test

Когда вы запускаете grunt test, вы увидите несколько предупреждений в консоли Yeoman. Не волнуйтесь, этого и следовало ожидать прямо сейчас, так как наши тесты в настоящее время терпят неудачу по двум причинам. Давайте исправим это.

Обновление конфигурации Karma

Во-первых, мы должны проверить конфигурацию Karma, чтобы увидеть, загружает ли он новые компоненты Bower, которые мы установили в шаге 7.

Oткройте karma.conf.js. На данный момент массив files должен выглядеть следующим образом:

   files: [
      // bower:js
      'bower_components/jquery/dist/jquery.js',
      'bower_components/angular/angular.js',
      'bower_components/bootstrap/dist/js/bootstrap.js',
      'bower_components/angular-animate/angular-animate.js',
      'bower_components/angular-cookies/angular-cookies.js',
      'bower_components/angular-resource/angular-resource.js',
      'bower_components/angular-route/angular-route.js',
      'bower_components/angular-sanitize/angular-sanitize.js',
      'bower_components/angular-touch/angular-touch.js',
      'bower_components/jquery-ui/jquery-ui.js',
      'bower_components/angular-ui-sortable/sortable.js',
      'bower_components/angular-mocks/angular-mocks.js',
      // endbower
      'app/scripts/**/*.js',
      'test/mock/**/*.js',
      'test/spec/**/*.js'
    ],

Bower прочитал в добавленных недавно зависимостях ('bowercomponents/jquery-ui/jquery-ui.js', 'bowercomponents/angular-ui-sortable/sortable.js') и автоматически добавил их в файл karma.conf.js для вас.

Обновление модульных тестов

Вы найдете модульные тесты построенными в папке test, потому открывайте test/spec/controllers/main.js. Это тестирование блока для вашего контроллера Angular MainCtrl, который мы должны изменить.

Ваш шаблонный тест по-прежнему ссылается на awesomeThings потому удалите следующий тест:

it('should attach a list of awesomeThings to the scope', function () { expect(scope.awesomeThings.length).toBe(3); });

И замените этот тест следующим:

it('should have no items to start', function () { expect(scope.todos.length).toBe(0); });

Oткройте scripts/controllers/main.js.

Удалите 3 пункта, которые мы добавили ранее, из декларации $scope.todos:

.todos = [];

Повторный запуск наших тестов с grunt test должен показать, что наши тесты сейчас проходят:

Добавляем больше модульных тестов

Этот тест покрывает только часть функциональности вашего приложения так что давайте добавим еще пару тестов, чтобы испытать добавление или удаление элементов:

it('should add items to the list', function () { scope.todo = 'Test 1'; scope.addTodo(); expect(scope.todos.length).toBe(1); }); it('should add then remove an item from the list', function () { scope.todo = 'Test 1'; scope.addTodo(); scope.removeTodo(0); expect(scope.todos.length).toBe(0); });

Ваш полный тестовый скрипт MainCtrl (test/spec/controllers/main.js) сейчас должен выглядеть так:

'use strict'; describe('Controller: MainCtrl', function () { // load the controller's module beforeEach(module('mytodoApp')); var MainCtrl, scope; // Initialize the controller and a mock scope beforeEach(inject(function (, ) { scope = .(); MainCtrl = ('MainCtrl', { : scope }); })); it('should have no items to start', function () { expect(scope.todos.length).toBe(0); }); it('should add items to the list', function () { scope.todo = 'Test 1'; scope.addTodo(); expect(scope.todos.length).toBe(1); }); it('should add then remove an item from the list', function () { scope.todo = 'Test 1'; scope.addTodo(); scope.removeTodo(0); expect(scope.todos.length).toBe(0); }); });

При повторном запуске тестов, мы должны увидеть что все проходит через 4 теста, которые выполняются:

Фантастика!

Написание модульных тестов облегчает улавливание ошибок, так как ваше приложение становится все больше и больше разработчиков присоединяются к вашей команде. Подмосточная особенность Yeoman делает написание модульных тестов проще, потому никаких оправданий для написания собственных тестов! ;)

« назад к обзору или к следующему шагу »

ШАГ 9: приготовьтесь к производству

Готовы показать ваше прекрасное todo приложение всему миру? Попробуем построить готовую к производству версию, ту, что мы можем грузить.

Оптимизация файлов для производства

Чтобы создать серийную версию своего приложения, мы захотим:

·         проконтролировать качество нашего кода,

·         запустить наши тесты,

·         объединить и уменьшить наши скрипты и стили, чтобы сэкономить на этих сетевых запросах,

·         оптимизировать изображения, если мы использовали какие-либо,

·         составить вывод всех препроцессоров, которые мы применяем, и

·         в целом сделать ваше приложение действительно компактным.

Пф! Удивительно, мы можем достичь всего этого просто командой:

$ grunt

Эта команда пройдет через задания Grunt и конфигурацию Yeoman и создаст для вас в Gruntfile.js версию приложения, которую мы можем грузить. Дайте ему минуту, и вам представят законченную сборку и отчет о том, как много сборке потребовалось времени для завершения и где это время было потрачено:

Ваше стройное, готовое к производству приложение теперь доступно в папке dist в корне вашего проекта mytodo. Вот файлы, которые вы можете поставить на свой сервер, используя FTP или любой другой сервис развертывания.

Создание и предварительный просмотр готового к производству приложения

Хотитепредварительно просмотреть производственное приложение локально? Это только еще одна простая команда grunt:

$ grunt serve:dist

Оно построит ваш проект и запустит локальный веб-сервер. Вы Герой!

« назад к обзору или к следующему шагу »

ШАГ 10: СДЕЛАЙТЕ TODOS СОХРАНЯЮЩИмися в локальном хранилище

Давайте вновь рассмотрим вопрос о предметах, не сохраняющихся после обновления браузера.

Если вы не имели никаких проблем с Шагом 7 и у вас не хватает времени, вы можете перейти к обертке кодовой лаборатории.

Установка пакета Bower

Чтобы легко достичь этого можно использовать другой Angular модуль, называемый "angular-local-storage" , который позволит нам быстро реализовать локальное хранилище. Опять, Bower приходит на помощь.

Запустите следующую команду:

$ bower install --save angular-local-storage

Добавьте локальное хранилище

Похоже на то, как мы добавляли jQueryUI и AngularUI Sortable в Шаге 7 чтоб сделать todos сортируемыми, нам нужно добавить ссылку в файл angular-local-storage.js в index.html.

Так как мы используем bower.json для отслеживания наших модулей, Ctrl+C для выхода из текущего процесса командной строки, а затем вновь перезапустите службу grunt serve, чтобы получить некоторую автоматизированную магию в вашем index.html.

Внизу index.html, вот что должно быть добавлено:

<script src="bower_components/angular-local-storage/dist/angular-local-storage.js"></script>

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

<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-touch/angular-touch.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>
<script src="bower_components/angular-ui-sortable/sortable.js"></script>
<script src="bower_components/angular-local-storage/dist/angular-local-storage.js"></script>
<!-- endbower -->
<!-- endbuild -->

Отредактируйте прикладной модуль mytodoApp (scripts/app.js), чтобы включить адаптер LocalStorageModule:

angular
  .module('mytodoApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.sortable',
    'LocalStorageModule'
])

Пока вы в app.js, также настройте localStorageServiceProvider на использование "ls" в качестве префикса имени localStorage, чтоб ваше приложение случайно не прочитало todos из другого приложения, используя те же имена переменных:

.config(['localStorageServiceProvider', function(localStorageServiceProvider){
  localStorageServiceProvider.setPrefix('ls');
}])

Наш модуль приложения должен выглядеть следующим образом:

'use strict';

angular
  .module('mytodoApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.sortable',
    'LocalStorageModule'
  ])
  .config(['localStorageServiceProvider', function(localStorageServiceProvider){
    localStorageServiceProvider.setPrefix('ls');
  }])
  .config(function () {
    
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

Вам также понадобится обновить контроллер (main.js) чтоб объявить зависимость от службы localStorage. Добавьте localStorageService в качестве второго параметра в функцию обратного вызова.

'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function (, localStorageService) {
    // (code hidden here to save space)
  });

Так что теперь, вместо того, чтобы читать наши todos из статического массива, мы будем читать их из локального хранилища, а затем хранить их в .todos взамен.

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

Поэтому, нам нужно удалить текущее описание .todos:

.todos = [];

И заменить его этим:

var todosInStore = localStorageService.get('todos');

.todos = todosInStore || [];

.('todos', function () {
  localStorageService.set('todos', .todos);
}, true);

Теперь у нас есть контроллер, который выглядит следующим образом:

'use strict';

angular.module('mytodoApp')
  .controller('MainCtrl', function (, localStorageService) {

    var todosInStore = localStorageService.get('todos');

    .todos = todosInStore || [];

    .('todos', function () {
      localStorageService.set('todos', .todos);
    }, true);

    .addTodo = function () {
      .todos.push(.todo);
      .todo = '';
    };

    .removeTodo = function (index) {
      .todos.splice(index, 1);
    };

  });

Если вы посмотрите на ваше приложение в браузере теперь, вы увидите, что нет элементов в списке задач. Приложение инициализирует массив todos с локального хранилища, а мы не дали ему никаких todo пунктов пока.

Идем дальше и добавим несколько элементов в список:

Теперь, когда мы обновим наш браузер, элементы сохраняются. Ура!

Мы можем подтвердить, действительно ли наши данные в настоящее время сохраняются в локальном хранилище, проверив панель ресурсов в Chrome DevTools и выбрав Local Storage с левой стороны:

Написание модульных тестов

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

Совет: Это не прямой ответ и включаетет знание о фиктивных услугах. Проверьте Передовой опыт Модульного тестирования в AngularJS, особенно секцию Копирующие услуги и модули в AngularJS.

Закрепите вопрос ng-repeat

Для дополнительного челенджа, функция ng-repeat не принимает несколько элементов с одинаковым значением. Попробуйте исправить это, глядя на "дорожку," и посмотрите, можете ли вы заставить ее работать. Существует также проблема восходящей цепочки, которая должна быть решена при использовании этого типа ng-repeat.

« назад к обзору или Все! Продолжайте »

Поздравления!

Нравится то, что вы видите? Yeoman может сделать больше.

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

Например, Angular генератор также поддерживает создание новых взглядов, директив и контроллеров для вас. Новый контроллер может быть построен запуском yo angular:route routeName, который создаст ваши файлы контроллера, но и обновит маршрут в app.js для вас. Мы также стараемся строить модульные тесты, где это возможно.

Чтобы узнать все команды Yeoman для генератора Angular, взгляните на файл generator readme.

Куда двигаться дальше

·         AngularJS (angularjs.org) помог нам написать это приложение Todo быстро и элегантно. Чтобы копнуть глубже в сладкие места AngularJS, взгляните на подробную документацию.

·         Grunt (gruntjs.com) имеет задачи для почти всего, что вы хотели бы сделать с вашим приложением, будь то компиляции CoffeeScript или подключение приложение к изготовленному на заказ промежуточному программному обеспечению, такому как PHP или Express. Ваше приложение Yeoman уже имеет Gruntfile.js, настроенное для вас, потому прочитайте о том, как настроить больше задач здесь.

·         Bower (bower.io) имеет растущую коллекцию легко устанавливаемых пакетов для добавления возможностей для вашего приложения. Просмотрите все пакеты, доступные через реестр Bower здесь.

·         Yeoman всегда развивается. Обязательно ознакомьтесь с yeoman.io для большего количества информации и следите за @yeoman и +Yeoman чтобы быть в курсе.

Вот и все от вашего мужчины-в-шляпе на данный момент. Благодарю!

« назад к обзору

Оригинал руководства находится здесь http://yeoman.io/