Показаны сообщения с ярлыком AngularJs. Показать все сообщения
Показаны сообщения с ярлыком AngularJs. Показать все сообщения

вторник, 22 ноября 2016 г.

AngularJS ошибки новичка

Изменение DOM-дерева

Перестаньте изменять DOM-дерево в контроллере, с помощью JQuery. Серьезно. Это относится к добавлению, удалению элементов, получению их содержимого, скрытие и показывание элементов. Для этого используйте встроенные директивы или пишите свои, когда это необходимо. 
Если есть проблемы с избавлением от этой привычки - попробуйте удалить JQuery из проекта. Серьезно. У Angular есть свой сервис $hppt и другие директивы, которые заменяют JQuery.  Angular поставляется со своим JQLite, его возможности используются при написании директив, особенно привязка к событиям.

Попытка дублировать функционал, который уже существует

Есть большая верятность, что не только вашему приложению понадобился данный функционал. Есть некоторый функционал, который постоянно пытаются реализовать по своему.
ng-repeat, частенько дублируется. Программисты пытаются добавить элементы, полученные от сервера,  используя JQuery. Это плохо. Именно для этого создан ng-repeat. И он справляется с этим отлично. Сохраниете данные в массив в своем $scope и выведите в DOM с помощью ng-repeat.
ng-show, тоже часто дублируют. Показ и скрытие элементов по условиню используя JQuery, частый паттерн для других приложений, но у Angular  есть решение лучше. ng-hide или ng-show, скрытие или показ элемента по условию, основываясь на булиеновском заначении. Пример:
 <div ng-show="!loggedIn"><a href="#/login">Click here to log in</a></div>
Обратите внимание на похожий  ng-disabled. Так же на мощный ng-switch, он должен быть использован вместо повторяющихся ng-shows.
ng-class  - последний из большой тройки. Применение класса для элемента, в ручную используя JQuery, основываясь на условии. Конечно в Angular есть способ лучше. Можно передать в ng-class список именн классов, разделенных проблемлом и их условий, вот пример:
<div ng-class="{ errorClass: isError, warningClass: isWarning, okClass: !isError && !isWarning }">...</div>
в ng-class передается объект, в котором перечислены CSS имена классов и условия их применения. Будут использоваться только те кслассы, условие для которых получилось true.

$watch и $apply

Двунаправленное связывание данных - это основа Angular. Тем неменее это не магия и в некоторых ситуациях тебе необходимо подсказать фреймворку правильное направление.
Когда ты связываешь значение с элемнтом используя ng-mode, ng-repeat и другие Angular создает $watch над этим значением. Далее, когда значение в области видимости изменится, все $watch'ы, наблюдающие за данным элементом, выполнятся, и обновится все остальное. 
Иногда, чаще всего, когда ты создаешь свои директивы, необходимо объявить собственные $watch, над переменными в области видимости, позволяющие директиве реагировать на изменения.
С другой стороны, когда ты изменяешь значение в области видимости, но приложение не реагирует. Angular проверяет изменение переменных в области видимости после того, как код отработал, например когда срабатывает ng-click, то Angular проверит изменения и отреагирует. Тем не менее, код вне Angular, должен самостоятельно вызвать метод scope.$apply(), чтоб произвести обновление.  Обычно это требуется в обработчиках событий в кастомных директивах.

Использование ng-repeat с другими директивами

ng-repeat - наиболее полезная и одна из самых мощных директив в Angular. Однако преобразование  DOM является трудоемким процессом. Поэтому применение других директив (ng-show, ng-hide, ng-controlle и др) к тому же элементу, что и ng-repeat может привести к проблемам. Если необходимо применить директиву ко всему объекту ng-repeat, оберните его в родительский элемент и примените директиву к нему. Если необходимо применить директиву к каждому элементу - примените директиву к элементу с ng-repeat.

$rootScope существует, но может создать проблемы

Области видимости в Angular формируются иерархично, наследуясь от основной области видимости верхушки дерева. Обычно, это можно игнорировать, т.к. у каждого вью имеют контроллеры, у которых есть своя область видимости.
Изредка,  есть данные, которые необходимо сделать глобальными для всего приложения. Для этого можно проинжектить $rootScope и установить в значение в нем, как в других областях видимости. Поскольку области наследуются от корневой области, эти значения будут доступны  директивам, таким как ng-show так же как значения в локальной $scope.
Конечно, использовать глобальное состояние плохо, а потому стоит использовать $rootScope с умом, как вы бы (надеюсь) обращались с глобальными переменными в любом другом языке. В частности, не используйте их для кода, только в данных. Если будет желание вставить функцию на $rootScope, то почти всегда лучше поместить его в сервис, который может быть инжектирован где это необходимо, и легко протестирован. С другой стороны, не создавайте сервис, чья единственная цель хранение и возврат бита данных.

PS мой перевод данной статьи

четверг, 3 ноября 2016 г.

AngularJs ng-option

Пользователю часто предоставляется выбор одно значения из многих, для этого удобно использовать   тэг <select>, все бы хорошо, но, логично, что то что мы показываем пользователю напрямую не может уйти в бэкэнд, для этого этого нам пригодится директива ng-option:

<select ng-model="dsInfo.settings.dataBaseType"
                  ng-options="type.value as type.name for type in dataBaseTypes"
                  required="true"/>

Что же тут происходит?!


  1. in работает, как директива  в ng-repeat
  2. for type - алиас, по которому можно будет обращаться к иттерируемому  объекту
  3. type.value будет устанавливать в модель, в данном случае dsInfo.settings.dataBaseType
  4. as type.name - то что будет показываться пользователю

четверг, 27 октября 2016 г.

AngularJs ng-repeat

Рассмотрим директиву ngRepeat.
Это обычный итератор по списку,  пример:
<div ng-repeat="i in [1,2,3,4,5]">{{i}}</div>
Вывод будет следующий: 12345
У данной директивы есть набор свойств, к которым можно обратить в области видимости данной директивы(в примере выше - до тега </div> )
Параметр Описание
$index Порядковый номер элемента [0 - length-1]
$first Возвращает true если первый элемент
$last Возвращает true если последний элемент
$middle Возвращает true если не первый и не последний элемента
$even true если четный элемент
$odd trye если нечетное число

Очень удобно с помощью данной директивы строить таблицы:
<table>
        <tr  >
            <th />
            <th ng-repeat="dayOfWeek in scheduleResult.dayOfWeeks" >
                {{dayOfWeek}}</th>

        </tr>
        <tr ng-repeat="recordElement in scheduleResult.recordDates" >
            <td >{{recordElement.date|date:'HH:mm'}}</td>
            <td ng-repeat="empty in recordElement.empties track by $index" ng-class="classStyle(empty)"
                ng-click="addRecord($index, recordElement.date, 'block', empty, scheduleResult.recordDates.indexOf(recordElement) );">{{empty}}</td>



        </tr>
    </table>
В recordElement.empties хранится массив, состоящий из true или false, в этом случае приходится использовать перебор по индексу track by $index", иначе будет ошибка Error: [ngRepeat:dupes]