Упреждающий выбор AngularJS при размытии

Я использую typeahead в своем проекте AngularJS, и я хотел бы, чтобы он выбирал запись, если я ввожу полное значение и щелкаю вне поля.

Я собрал пример того, что я имею в виду

http://plnkr.co/edit/NI4DZSXofZWdQvz0Y0z0?p=preview

<input class='typeahead' type="text" sf-typeahead options="exampleOptions" datasets="numbersDataset" ng-model="selectedNumber">

Если я наберу «два» и нажму «два» в раскрывающемся списке, я получу полный объект {id: 2, имя: «два»}. Это хорошо, однако, если я наберу «два» и перейду к следующему полю, не выбирая, есть ли способ принять верхнюю часть списка при потере фокуса в текстовом поле?


person map7    schedule 06.08.2014    source источник
comment
Должна ли использоваться директива typeahead, которую вы используете в примере? Если нет, вы можете попробовать angular-ui (официально из сообщества angularjs). angular-ui.github.io/bootstrap . Их typehead уже поддерживает то, что вы хотите.   -  person hutingung    schedule 11.08.2014
comment
@map7 интересно, работает ли мое решение для вас, потому что я оставил его несколько общим.   -  person bhantol    schedule 12.08.2014
comment
@bhantol Это похоже на то, что мне нужно, мне нравится пример. Я просто пытаюсь протестировать это решение в своем большом приложении.   -  person map7    schedule 14.08.2014
comment
Спасибо за все ответы, я попробовал их все и остановился на ответе Майка, поскольку он лучше всего соответствует моей цели, и пример действительно помог. Мне также нравится тот факт, что это работает только в том случае, если пользователь вводит целое число, а затем щелкает фокус. Таким образом, я думаю, это не смущает пользователя.   -  person map7    schedule 18.08.2014


Ответы (3)


Я с EnigmaRM в том, что ngBlur, кажется, способ делать то, что вы хотите. Однако я согласен с другими, что это может быть несколько странно для конечных пользователей. Моя реализация ниже (и в plnkr). Обратите внимание, что я запускаю ngBlur, но применяю модель только тогда и только тогда, когда есть только одно совпадение от Bloodhound, и совпадение является точным. Я думаю, что это, вероятно, лучшее из обоих миров, и надеюсь, что это даст вам достаточно, чтобы продолжать.

$scope.validateValue = function() {
  typedValue = $scope.selectedNumber;
  if(typedValue.num !== undefined && typedValue.num !== null)
  {
    return;
  }
  numbers.get(typedValue, function(suggestions) {
    if(suggestions.length == 1 && suggestions[0].num === typedValue) {
      $scope.selectedNumber = suggestions[0];
    }
  });
};
person Mike    schedule 15.08.2014

Я не уверен, что хотел бы иметь такую ​​​​функциональность в своем приложении. Пользователь на самом деле ничего не выбрал. Так что выбор чего-то для них вызовет разочарование.

Но я понимаю, что часто нужны странные требования. В этом случае я бы атаковал его, используя ngBlur. Назначьте функцию, которая будет вызываться при размытии. Вы можете получить содержимое ng-model, а затем просмотреть свои данные (при условии, что они статические и не отправляются через сервер), чтобы найти совпадение.

Скорее всего, вы можете просто посмотреть исходный код вашей директивы typeahead и вырезать часть, которая выполняет сравнение, а затем выбрать первый элемент в массиве.

person EnigmaRM    schedule 11.08.2014
comment
Просто ngBlur не будет работать, потому что к тому времени, когда происходит ngBlur, все предложения фактически исчезают. У вас не будет времени перехватить существующие предложения, не выполнив еще один запрос в механизме предложений. - person bhantol; 11.08.2014
comment
Я понимаю твою точку зрения @bhantol. Никогда не предполагал, что он сможет получить доступ к предложениям. Не уверен, что вы прочитали мой пост полностью. Он должен был бы получить пользовательский ввод, а затем прокрутить свои данные, чтобы найти совпадение самостоятельно. - person EnigmaRM; 11.08.2014
comment
Попробуйте plnkr.co/edit/t2ohPy?p=preview — полное значение не доступны на входе. например при вводе 't' вы получите 't', как и должно быть. Typeahead не ставит первое предложение «два» в качестве значения. О ngBlur - я должен был упомянуть в своем комментарии, что Typeahead также реализует обработчик размытых событий. Полное значение («два») не фиксируется в поле. И когда это происходит, входное значение равно t, а не двум. - person bhantol; 11.08.2014

К сожалению, базовый компонент не генерирует никаких событий для этого условия. Это усложнит решение. Однако, когда значение вводится и происходит волшебство Typehead, вы можете дополнить эти события и перехватить их, чтобы обновить свой ngModel.

Я создал plnkr на основе вашего plnkr и, хотя не очищал, но это рабочий plnkr делать то, что вам нужно.

Суть этого заключается в следующем коде, однако вы можете разместить этот код там, где он лучше всего подходит
Объяснение ниже:

          //Crux - this gets you the Typeahead object 
          var typeahead = element.data('ttTypeahead');              

          //This gets you the first
          var datum = typeahead.dropdown.getDatumForTopSuggestion();

          if (datum){
            //you can do lot of things here however 
            //..I tried to - fill in the functionality best suited to be provided by Typeahead
            //for your use case. In future if Typeahead gets this 
            //..feature you could remove this code
            typeahead.eventBus.trigger("hasselections", datum.raw, datum.datasetName);
          } 

В приведенном выше коде вы также можете сохранить датум где-нибудь в области видимости, чтобы потом делать с ним все, что захотите. По сути, это ваш объект {num: 'Six'} Затем вы также можете использовать ngBlur, чтобы установить его где-нибудь (однако созданный мной plnkr не нуждается в этих уловках.)

Затем дальше вниз - значение ngModel устанавливается, как показано ниже.

   element.bind('typeahead:hasselections', function(object, suggestion, dataset) {
      $timeout(function(){
        ngModel.$setViewValue(suggestion);
      }, 1);
      //scope.$emit('typeahead:hasselections', suggestion, dataset);
    });
person bhantol    schedule 11.08.2014
comment
Одна из причин, по которой нам может понадобиться подобная функциональность, заключается в том, чтобы предоставить аналитику/информацию о главном предложении, которое появилось. - person bhantol; 11.08.2014