Пример использования AngularJS

28.07.2014

Пример работы с AngularJS

Сейчас много пишут про AngularJs, но до недавнего времени обходился обычным jQuery и не думал о чем-то другом, пока в нашей команде не появился новый программист, которому очень нравится работать над фронтэндом. Он то как раз и показал все прелести ангулара, хз как я раньше то жил :)

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

Задача: страница новостей, с сортировкой по дате и количеству лайков. (исходники)

1. Начальные условия

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

  • id
  • title
  • text
  • like_count
  • created_date

Бэкэнд работает на yii. Имеется следующая таблица:

CREATE TABLE news
(
    id int PRIMARY KEY NOT NULL,
    title varchar (255) NOT NULL,
    text text  NOT NULL,
    like_count int DEFAULT 0 NOT NULL,
    created_date timestamp  NOT NULL
);

И соответствующая ей модель.
Далее в лайоуте подключаем сам ангулар и файл контроллера(пока пустой): https://ajax.googleapis.com/ajax/libs/angularjs/1.... и js/controllers/NewsController.js (не могу использовать скрипты подключения здесь)

Не забываем добавить директиву ng-app в тег html. Эта директива указывает корневой элемент ангулар-приложения.

Не парьтесь, просто укажите её либо в html, либо в body, а кому интересно - почитайте подробнее документацию.
Нам нужно вывести список новостей с возможностью сортировки, далее буду показывать всё по этапам.

2. Список новостей

Сейчас создадим страницу где будет сам список, теперь уже нужен NewsController.php, а в нём вот такой index-экшен:

public function actionIndex() {
    $this->pageTitle = 'Список новостей';
    $this->render('index');
}

Сложнейший экшен, не правда ли?! Остается вьюха и js-контроллер. Начнем со вьюхи:

Html init(Полный код можно посмотреть здесь).

Разберем всё по-порядку:

  1. ng-controller=”NewsController” - указываем имя класса контроллера, подключенного к этой вьюхе. Далее мы напишем этот класс в файле NewsController.js
  2. ng-init="getNews()" - указываем метод класса, который вызывается при инициализации нашего js-контроллера. Это обычный метод, который будет вызван первым(не будем ничего усложнять).
  3. ng-repeat="newsItem in news" - angularjs создан на основе MVC, контроллер мы напишем, а внутри этого контроллера будет инициализирована модель news, таким образом мы сейчас проходимся по массиву модели news и в каждой итерации создаем строку таблицы.

Стараюсь описать всё как можно более простыми словами, если будут появляться вопросы - пишите в комментариях.

Теперь давайте напишем ангулар-контроллер:

function NewsController($scope, $http) {
    $scope.news = [];

    $scope.getNews = function() {
        $http({
            url: '/news/getNews',
            method: 'GET'
        }).success(function(data) {
            angular.forEach(data, function(newsItem) {
                newsItem.like_count = Number(newsItem.like_count);
                $scope.news.push(newsItem);
            });
        });
    }
}

Разбираем:

  1. function NewsController($scope, $http) - имя контроллера и сервисы ангулара. В нашем случае это $scope - это внутренняя область видимости контроллера, которая содержит все модели, методы к которым мы обращаемся в представлении. Не знаю как это лучше объяснить, дальше на практике поймете о чем я. $http - сервис предоставляющий методы для работы с http. К примеру сделать get/post запрос на сервер (аналог $.ajax в jQuery).
  2. $scope.news = []; - помните, во вьюхе выше мы делали ng-repeat по модели новостей. Вот как раз мы говорим что модель news содержит пустой массив, всё это хранится в области видимости ангулар-контроллера $scope. На практике просто обращайтесь к своим атрибутам и методам контроллера через $scope и всё, а во вьюхе напрямую.
  3. $scope.getNews = function() - выше мы делали ng-init=”getNews()” - инициализировали область видимости контроллера.
  4. $http({}); - сделали GET запрос по урлу /news/getNews и если данные успешно получили, то положили их в модель news($scope.news.push(newsItem)). Поясню - сервис $http ждёт ответа в json’e.

И последнее - мы не написали метод news/getNews:

public function actionGetNews() {
    $comments = Yii::app()->db->createCommand('SELECT * FROM news')->queryAll();
    $this->renderJSON($comments);
}

protected function renderJSON($data) {
    header('Content-type: application/json');
    echo CJSON::encode($data);
    Yii::app()->end();
}

Проверяем что у нас получилось:

Начальная таблица

Всё отлично выводится, осталось сделать сортировку по дате и количеству лайков.

3. Сортировка моделей

Теперь давайте добавим возможность сортировки новостей. Добавляем ссылки перед таблицей:

Ссылки для сортировки

Из кода видно, что при клике вызывается метод setOrder в который передается поле по которому происходит сортировка и порядок сортировки (ASC / DESC).

Кроме этого давайте зададим сортировку при инициализации таблицы, для этого немного исправим директиву ng-repeat, добавим фильтр:

Пример ngOrder

Где:

  1. orderOptions.field - orderOptions - объект данных в контроллере, который имеет свойство field - поле по которому будет сортировка
  2. reverseOptions[orderOptions.field] - объект, который возвращает прямой или обратный порядок сортировки, исходя из переданного в него поля. К примеру для даты создания - прямой порядок.

Добавляем объекты сортировки в контроллер:

$scope.orderOptions = {
    field: 'created_date'
};
$scope.reverseOptions = {};

Определяем метод сортировки (setOrder):

$scope.setOrder = function(field, reverse) {
    if ($scope.orderOptions.field != field) {
        $scope.reverseOptions[field] = reverse;
    } else {
        $scope.reverseOptions[field] = !$scope.reverseOptions[field];
    }
    $scope.orderOptions.field = field;

    return false;
}

Суть метода в том, что он сравнивает порядок сортировки по полю, с тем что есть и если надо, меняет порядок на обратный.
Ну разжую: если был created_date ASC, меняем на created_date DESC.

Проверяем что у нас получилось:

Дефолтовый порядок сортировкиИ теперь отсортируем по дате:

Сортировка по дате

Всё отлично работает.
Кому интересно - попробуйте добавить визуальное отображение порядка сортировки для ссылок(стрелочки вверх/вниз).

4. Итого

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

Забрать рабочий пример вы можете с моего гитхаб-аккаунта, в папке protected/data лежит дамп БД

Похожие статьи:

blog comments powered by Disqus
Наверх