2

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

Вот HTML:

<div my-autosuggest> 
    <input type="text" my-autosuggest-input> 
    <ol> 
     <li ng-repeat"item in items" my-autosuggest-list>...</li> 
    </ol> 
</div> 

Я не хочу использовать шаблоны для создания <li> элементов. (Я хочу, чтобы он был гибким, чтобы использовать любой элемент в любом порядке и, возможно, некоторые дополнительные элементы между ними для списка и выпадающего списка)

Жесткая часть - отвечать на клавиши со стрелками на входе, чтобы выделить следующий/prev в списке. Как я могу позволить другой директиве my-autosuggest-list знать, что он должен выбрать следующий элемент из директивы my-autosuggest-input.

Обратите внимание, что я мог бы иметь несколько autosuggests в одном контроллере, как это:

<div ng-controller="MyController"> 
    <div my-autosuggest> 
     <input type="text" my-autosuggest-input> 
     <ol> 
      <li ng-repeat"item in items" my-autosuggest-list>...</li> 
     </ol> 
    </div> 
    <div my-autosuggest> 
     <ol> 
      <li ng-repeat"item in items" my-autosuggest-list>...</li> 
     </ol> 
     <input type="text" my-autosuggest-input> 
    </div> 
</div> 

До сих пор я пытался $watch для изменения индекса, но иногда часы обыкновение называться для некоторых элементов в списке (возможно, это ошибка). $ широковещательная передача не будет работать, потому что вход может быть обернут другим контроллером или внутри другого элемента, поэтому трансляция не будет услышана в списке.

Я также попытался поместить переменную для каждой автозагрузки в корневую область, но порядок, в котором директивы вызываются не всегда от родителя к дочернему, поэтому я не могу инициализировать эту переменную и создавать новую каждый раз, когда вызывается my-autosuggest потому что my-autosuggest-input или другие могут быть вызваны до этого.

Любое предложение о том, как проектировать это с угловой оценено.

ответ

2

Предполагая, что my-autosuggest-input и my-autosuggest-list всегда находятся внутри my-autosuggest. Для этого вы можете использовать ряд событий $emitted и $broadcast.

Внутри my-autosuggest-input 'функция связи добавит $emit при нажатии клавиши со стрелкой нажата:

element.on('keyup', function() { 
    // Figure out if this is an arrow key, if so: 
    $scope.$emit('listSelect', { message: 'prevItem' }); // Or 'nextItem' 
}); 

Внутри my-autosuggest ссылка или функция контроллера добавить:

// Add a controllerId, so that the listener doesn't handle its own events. 
$scope.controllerId = Math.random().toString(); 
$scope.$on('listSelect', function (e, data) { 
    if ($scope.controllerId !== data.controllerId) { 
     $scope.$broadcast('listSelect', { 
      controllerId: $scope.controllerId, 
      message: data.message 
     }); 
    } 
}); 

Наконец, внутри my-autosuggest-list-х функция связи или контроллер добавить:

$scope.$on('listSelect', function (e, data) { 
    if (data.message === 'nextItem') { 
     // Highlight next item. 
    } else { 
     // Highlight previous item. 
    } 
}); 

В этом случае my-autosuggest направляет любые listSelect события от любого из своих детей всем своим детям.

+0

спасибо, это выполнит эту задачу, единственная проблема в том, что основная директива 'my-autosuggest' будет содержать много шаблонов. Для каждого события, которое запускается вводом, выпадающим списком или списком (например, выпадающее меню, hidedropdown, выберите элемент списка, ...) Мне нужно добавить слушателя в директиву 'my-autosuggest' и перепрограммировать его. Дайте мне знать, можете ли вы придумать какое-либо другое решение, чтобы избежать дополнительного кода шаблона. – danial

+0

Кажется, что это не работает, $ scope. $ On ('listSelect', function (e, data) { $ scope. $ Broadcast ('listSelect', data); }); вызовет бесконечный цикл – danial

+0

Я бы поиграл с разными именами событий/данными, чтобы уменьшить шаблон.Например, у вас может быть одно событие с именем «toList», адресованное компоненту списка, и объект данных, отправленный с событием, может содержать фактическое сообщение, например «выбрать следующий элемент». Вы делаете его действительно общим с событием «routeAutoSuggest» и объектом данных, например '{target: 'list', action: 'show next item'}'. Тогда 'my-autosuggest' должен иметь только один прослушиватель. –

 Смежные вопросы

  • Нет связанных вопросов^_^