+7 495 008 8452 пн.-пт. 10:00 – 17:00
Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.


Статья про Angular и Битрикс d7

Сейчас проходит олимпиада (http://academy.1c-bitrix.ru/konkurs/) Битрикс по разработке сайтов. Если посмотрим на тестовое задание (http://academy.1c-bitrix.ru/konkurs/s...index.html), то мы увидим под капотом не jQuery, а AngularJS (http://angularjs.org/).  Давайте рассмотрим преимущества данного фреймворка. Посмотрим как можно его использовать в своих проектах, как связать его с данными сайта и немного расширим свои знания ;)

Итог посмотреть результат можно тут (http://onepage.bx-shef.by/article-ang...ar-bitrix/)



Вся суть ангуляра (http://angular.ru/misc/faq) сводится к двунаправленной связке данных из js и их представлением на странице. Прибавим сюда директивы (http://angular.ru/guide/directive), промисы/promise (http://angular.ru/api/ng.$q) и тестирование(http://angular.ru/guide/dev_guide.unit-testing). В итоге эта махина действительно становится Супер-героическим фреймворком для веб-приложений от компании google.


Давайте на пример разберем работу.

Задача:
  • вывести список пользователей
  • сделать по фильтр (имя, фамилия)
  • сделать карточку пользователя
Все это показать адаптивно и симпатично.



Для решения задачи будем использывать:
  1. bootstrap (http://getbootstrap.com/)
  2. AngularJS (http://angularjs.org/)
  3. Bitrix D7 (http://dev.1c-bitrix.ru/learning/cour...=3913.5062)
Начнем с шаблона

За основу возьмем пример Narrow jumbotron (http://getbootstrap.com/examples/jumb...on-narrow/)

Преобразуем и получим:

f1.jpg
Исходный код страницы (https://bel.bitrix24.ru/docs/pub/20ef8...index.html)

Теперь добавим ангуляр

подключаем JS
....
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-route.min.js"></script>
<script src="lib/angular/ui-bootstrap-tpls-0.10.0.min.js"></script>
</body>
 
указываем зависимости
angular.module('demo.shef', [
     'ngRoute',
     'ui.bootstrap'
])
расставим связки на страницы

* название приложения
 <html lang="ru" ng-app="demo.shef">
* контент заменим на "включаемую область"
 <div class="content">
         <div ng-view ><div>
</div>
* расставим правила обработки адресов
 .config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/list', {templateUrl: 'partials/list.html', controller: 'ListCtrl'});
  $routeProvider.when('/user/:id', {templateUrl: 'partials/user.html', controller: 'UserCtrl'});
  $routeProvider.otherwise({redirectTo: '/list'});
}])
* застолбим обработчики данных
 .controller('ListCtrl', ['$scope', '$log', function($scope, $log) {
}])
.controller('UserCtrl', ['$scope', '$log', function($scope, $log) {
}]) 

Разнесем контент (шаблоны контента) по двум файлам partials/list.html и partials/user.html
Ангуляр сам их загрузит когда нужно будет

Для тестирования укажем ссылки:
* в списке
<tr>
<td><a href="#/user/1">1</a></td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr> 
* и в карточке соответственно
 <ul class="pager">
     <li class="previous"><a href="#/list">&larr; К списку</a></li>
</ul> 
Исходный код (https://bel.bitrix24.ru/docs/pub/66bbf...step_2.zip) стоит смотреть на сервере (можно локальном)

Теперь посмотрим на d7


Создадим модуль.
В папку /local/modules/ положим эту болванку (https://bel.bitrix24.ru/docs/pub/25a27.../local.zip)
И устанавливаем его в системе /bitrix/admin/partner_modules.php?lang=ru
f3.jpg


Чуть подробнее об модуле.
файл /local/modules/shef.def/admin/controller.php
Контроллер. Принимает запрос от клиента, проверяет сессию, и подключает нужный класс для обработки запроса.
Т.е. вы через запрос шлете get('\Shef\Def\Project\Users::getUsers') - а контроллер сам подключит нужный php класс (\Shef\Def\Project\Users) и сам вызовет нужный статический метод (getUsers)
Так же присутствует проверка на namespace, что бы лишнего не дергали ))
if(stristr($_REQUEST['param1'][0], 'Shef') === false) ...

файл /local/modules/shef.def/lib/response.php
Класс для формирования ответов клиенту. Он из массива формирует JSON нужного формата и отправляет

файл /local/modules/shef.def/lib/project/users.php
Собственно класс, который нам возвращает список пользователей.

Суть структуры. Писать запрос к нужным классам в определенном (стандартном) формате. Это позволяет масштабировать решение для любых потребностей (выборка, внесение данных и т.п.)

Теперь соединим Ангуляр и наш модуль
Переименуем index.html в index.php и добавим служебную часть эпилога и пролога на страницу. И в параметр запишем sessid пользователя
<?require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");?>
<!DOCTYPE html>
<html lang="ru" ng-app="demo.shef"  ng-init="_sessid='<?=bitrix_sessid();?>'">
...
<?require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");?>

Добавим в Ангуляр сервис для общения с сервером и соединим его с контроллерами

* включаем еще одну зависимость
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-resource.min.js"></script> 
* подключаем ngResource
angular.module('demo.shef', [
     'ngRoute',
     'ngResource',
     'ui.bootstrap'
])
* создаем сервис
.service('projectResource', ['$resource', '$rootScope', function($resource, $rootScope){
     return $resource(
          '/local/modules/shef.def/admin/controller.php?param1=:param1&param2=:param2&sessid=:sessid',
          {sessid: $rootScope._sessid}
     );
}])
.controller('ListCtrl', ['$scope', 'projectResource', '$log', function($scope, projectResource, $log) {
}])
.controller('UserCtrl', ['$scope', 'projectResource', '$log', function($scope, projectResource, $log) {
}]);

Теперь мы можем сделать запрос к модулю и получить список пользователей
.controller('ListCtrl', ['$scope', 'projectResource', '$log', function($scope, projectResource, $log) {
     $scope.items = {};
     var resultGetUsers = projectResource.get({
          param1: ['\\Shef\\Def\\Project', '\\Users', 'getUsers'],
          param2: []
     }, function(){
          if(resultGetUsers.response.status == 'success'){
               $scope.items = resultGetUsers.values;
               $log.debug($scope.items);
          }else{
               $scope.items = {};
               alert(resultGetUsers.response.message);
          }
     });
}])
Или получить пользователя по ID (берем из URL)
.controller('UserCtrl', ['$scope', '$routeParams', 'projectResource', '$log', function($scope, $routeParams, projectResource, $log) {
     $scope.item = {};
     $scope.params = $routeParams;
    
     var resultGetUser = projectResource.get({
          param1: ['\\Shef\\Def\\Project', '\\Users', 'getUser'],
          param2: [$scope.params.id]
     }, function(){
          if(resultGetUser.response.status == 'success'){
               $scope.item = resultGetUser.values;
               $log.debug($scope.item);
          }else{
               $scope.item = {};
               alert(resultGetUser.response.message);
          }
     });
}]);
f4.jpg
На несуществующий ID получим alert

f41.jpg

Исходный код результата (https://bel.bitrix24.ru/docs/pub/f6d68...step_3.zip)

Теперь выведем результаты в HTML

* для страницы пользователя
<dl class="dl-horizontal">
          <dt>Имя:</dt>
          <dd>{{item.NAME}}</dd>
          <dt>Фамилия:</dt>
          <dd>{{item.FAMILIA}}</dd>
          <dt>Отчество:</dt>
          <dd>{{item.OTCHESTVO}}</dd>
</dl>
f6.jpg
Видно что {{item.OTCHESTVO}} не определено и не выводится


* для списка пользователей
     <table class="table table-hover mb_2">
          <thead>
               <tr>
                    <th>#</th>
                    <th>Имя</th>
                    <th>Фамилия</th>
                    <th>Логин</th>
               </tr>
          </thead>
          <tbody>
               <tr ng-repeat="(itemId, item) in items">
                    <td><a ng-href="#/user/{{itemId}}">{{$index+1}}</a></td>
                    <td>{{item.NAME}}</td>
                    <td>{{item.FAMILIA}}</td>
                    <td>{{item.LOGIN}}</td>
               </tr>
          </tbody>
     </table>
f61.jpg


  • Строки таблицы заполняются перебором (ng-repeat)
  • Номер формируется через индекс цикла
  • Ссылка формируется отложено (ng-href)
Ну и фильтр
Это самое простое. Настраиваем input на хранение значения фильтра
<input type="text" class="form-control" ng-model="q">
И соединяем его с циклом
<tr ng-repeat="(itemId, item) in items| filter:q">
Итого - вводим значение в фильтре и оно сразу применяется для списка

f7.jpg

Итог посмотреть результат можно тут (http://onepage.bx-shef.by/article-ang...ar-bitrix/)

PS: По коду статьи постраничная навигация планировалась. Однако оказалось, что она сильно усложняет понимание. Поэтому в итоге она скрыта.

Назад в раздел

Подписаться на новые материалы раздела:












CAPTCHA