Если вы запускаете проект AngularJS, возможно, вы захотите, чтобы все компоненты были написаны на Angular. Хотя, безусловно, возможно повторное использование существующих плагинов jQuery, добавление jQuery в директиву не всегда является правильным способом сделать что-то. Мой совет — сначала проверить, может ли та же самая вещь быть реализована с помощью чистого Angular более простым / лучшим способом. Это сохраняет код вашего приложения чистым и поддерживаемым. Это руководство, предназначенное для начинающих, поможет читателям создать простой виджет TypeAhead с AngularJS.
обзор
В этом уроке мы собираемся создать простой виджет TypeAhead, который создает предложения, как только кто-то начинает вводить текстовое поле. Мы спроектируем приложение таким образом, чтобы конечный продукт был легко настраиваемым и мог быть легко подключен к существующей системе. Основные этапы процесса создания:
- Создайте фабрику, которая взаимодействует с RESTful API и возвращает JSON, который будет использоваться для предложений автозаполнения.
- Создайте директиву, которая будет использовать данные JSON и инкапсулировать поле ввода typeahead.
- Сохраняйте директиву настраиваемой, чтобы конечные пользователи могли настраивать следующие параметры.
Параметры конфигурации
- Точные свойства объекта JSON, которые нужно показать как часть предложений.
- Модель в области видимости контроллера, которая будет содержать выбранный элемент.
- Функция в области видимости контроллера, которая выполняется при выборе элемента.
- Текст-заполнитель (подсказка) для поля ввода typeahead.
Шаг 1: Создание фабрики для получения данных
В качестве первого шага давайте создадим фабрику, которая использует службу $http
Angular для взаимодействия с RESTful API. Посмотрите на следующий фрагмент:
var typeAhead = angular.module('app', []);
typeAhead.factory('dataFactory', function($http) {
return {
get: function(url) {
return $http.get(url).then(function(resp) {
return resp.data; // success callback returns this
});
}
};
});
Предыдущий код создает фабрику с именем dataFactory
Мы не будем вдаваться в подробности фабрики, но нам нужно кратко понять, как работает служба $http
Вы передаете URL в функцию get()
Другой вызов then()
get()
Это обещание разрешается возвращаемым значением then()
Итак, внутри нашего контроллера мы не взаимодействуем напрямую с $http
Вместо этого мы запрашиваем экземпляр factory в контроллере и вызываем его функцию get()
Итак, наш код контроллера, который взаимодействует с фабрикой, выглядит следующим образом:
typeAhead.controller('TypeAheadController', function($scope, dataFactory) { // DI in action
dataFactory.get('states.json').then(function(data) {
$scope.items = data;
});
$scope.name = ''; // This will hold the selected item
$scope.onItemSelected = function() { // this gets executed when an item is selected
console.log('selected=' + $scope.name);
};
});
В предыдущем коде используется конечная точка API с именем states.json
Когда данные будут доступны, мы сохраняем список в items
Мы также используем name
Наконец, функция onItemSelected()
Шаг 2: Создание Директивы
Давайте начнем с директивы typeahead
typeAhead.directive('typeahead', function($timeout) {
return {
restrict: 'AEC',
scope: {
items: '=',
prompt: '@',
title: '@',
subtitle: '@',
model: '=',
onSelect: '&'
},
link: function(scope, elem, attrs) {
},
templateUrl: 'templates/templateurl.html'
};
});
В директиве мы создаем изолированную область видимости, которая определяет несколько свойств:
-
items
-
prompt
typeahead
title
-
subtitle
title
subtitle
typeAhead
Большинство виджетовtitle
Обычно они (если не всегда) имеют два поля для каждой записи в выпадающих предложениях. Если у объекта JSON есть дополнительные свойства, это действует как способ передачи двух свойств, которые будут отображаться в каждом предложении в раскрывающемся списке. В нашем случаеsubtitle
model
-
onSelect
-
{
"name": "Alabama",
"abbreviation": "AL"
}
Примечание: пример ответа JSON показан ниже:
<input type="text" ng-model="model" placeholder="{{prompt}}" ng-keydown="selected=false" />
<br/>
<div class="items" ng-hide="!model.length || selected">
<div class="item" ng-repeat="item in items | filter:model track by $index" ng-click="handleSelection(item[title])" style="cursor:pointer" ng-class="{active:isCurrent($index)}" ng-mouseenter="setCurrent($index)">
<p class="title">{{item[title]}}</p>
<p class="subtitle">{{item[subtitle]}}</p>
</div>
</div>
Шаг 3: Создайте шаблон
Теперь давайте создадим шаблон, который будет использоваться директивой.
prompt
Сначала мы визуализируем текстовое поле ввода, где пользователь будет печатать Приглашение свойства области присваивается атрибуту placeholder
Далее мы перебираем список состояний и отображаем name
abbreviation
Эти имена свойств настраиваются через свойства области title
subtitle
Директивы ng-mouseenter
ng-class
Далее мы используем filter:model
Наконец, мы использовали директиву ng-hide
Для свойства selected
true
handleSelection()
false
Шаг 4: Обновите функцию link
Далее, давайте обновим функцию link
link: function(scope, elem, attrs) {
scope.handleSelection = function(selectedItem) {
scope.model = selectedItem;
scope.current = 0;
scope.selected = true;
$timeout(function() {
scope.onSelect();
}, 200);
};
scope.current = 0;
scope.selected = true; // hides the list initially
scope.isCurrent = function(index) {
return scope.current == index;
};
scope.setCurrent = function(index) {
scope.current = index;
};
}
Функция handleSelection()
model
Затем мы сбрасываем current
selected
Далее мы вызываем функцию onSelect()
Добавлена задержка, потому что назначение scope.model=selecteditem
Желательно выполнить функцию обратного вызова области контроллера после обновления модели выбранным элементом. Вот почему мы использовали сервис $timeout
Кроме того, функции isCurrent()
setCurrent()
Следующий CSS также используется для завершения процесса выделения.
.active {
background-color: #C44741;
color: #f2f2f2;
}
Шаг 5: Настройте и используйте директиву
Наконец, давайте вызовем директиву в HTML, как показано ниже.
<div class="container" ng-controller="TypeAheadController">
<h1>TypeAhead Using AngularJS</h1>
<typeahead items="items" prompt="Start typing a US state" title="name" subtitle="abbreviation" model="name" on-select="onItemSelected()" />
</div>
Вывод
Из этого туториала Вы узнаете, как создать виджет AngularJS TypeAhead с параметрами конфигурации. Полный исходный код доступен для скачивания на GitHub . Не стесняйтесь комментировать, если что-то неясно или вы хотите что-то улучшить. Кроме того, не забудьте проверить живую демонстрацию .