Тип Angular-UI: показывать метку, но привязывать только к значению

Я использую тип Angular-UI следующим образом:

<input type="text" ng-model="myModel" typeahead="o.value as o.text for o in options | filter:$viewValue | limitTo:5" typeahead-editable="false" />

привязан к такой модели, как:

var options = [
    {"value": 1, "text": "value1"},
    {"value": 2, "text": "value2"},
    ...
];

Он правильно показывает текст параметров, но когда я выбираю элемент, он показывает значение внутри текстового поля. Модель правильно привязана только к значению (а не ко всему объекту модели).

Можно ли отображать внутри текстового поля «текст» (а не «значение») после выбора, сохраняя привязку модели только к значению (т.е. когда я выбираю определенный «текст», модель обновляется с помощью «значение» )?


person Matteo Piazza    schedule 30.10.2013    source источник
comment
Не могли бы вы использовать typeahead-on-select для установки выбранного значения. Удалите o.value as из типа впереди.   -  person epitka    schedule 17.12.2013


Ответы (6)


Это не идеально, но атрибут typeahead-input-formatter обеспечивает обходной путь до тех пор, пока не будет предоставлено исправление. (Plunker из поток github).

HTML:

<input type="text" 
       ng-model="myModel" 
       typeahead="o.value as o.text for o in options | filter:$viewValue | limitTo:5" 
       typeahead-editable="false" 
       typeahead-input-formatter="formatLabel($model)" 
/>

Функция контроллера AngularJs:

$scope.formatLabel = function(model) {
   for (var i=0; i< $scope.options.length; i++) {
     if (model === $scope.options[i].value) {
       return $scope.options[i].text;
     }
   }
};
person krimhorn    schedule 27.02.2014
comment
Примечание. Если у вас есть более простая задача форматирования, например доступ к атрибуту модели, вы можете просто выполнить typeahead-input-formatter="$model.firstName + ' ' + $model.lastName". - person Nick Merrill; 17.06.2014
comment
И вы можете использовать встроенную функцию Angular для перебора коллекции или массива: angular.forEach docs .angularjs.org/api/ng/function/angular.forEach - person zelibobla; 19.12.2014
comment
@NickM, который не будет работать, если вы используете синтаксис o.value as o.text, поскольку значение $model отражает проанализированное значение o.value, в данном случае простая строка - person jusopi; 12.06.2015
comment
Привет. Удалось ли вам заставить это работать с исходным кодом Ajax? Вот отчет об ошибке GitHub - person Murali Murugesan; 09.08.2015
comment
@NickM сохраняет пробелы в элементе управления вводом - person Yehia; 31.12.2015
comment
К сожалению, этот обходной путь не работает, если вы заполняете ввод асинхронно. - person Paul Taylor; 26.01.2016
comment
@NickMerrill @jusopi для этого вы должны использовать только o, а не o.value. @yehia использует typeahead-input-formatter="$model && ... для очистки ввода, когда нет значения - person Bernardo Dal Corno; 15.02.2019

Попробуйте изменить код с

typeahead="o.value as o.text for o in options | filter:$viewValue | limitTo:5"

to

typeahead="o as o.text for o in options | filter:$viewValue | limitTo:5"
person UmaKiran    schedule 26.02.2014
comment
но это устанавливает для объекта значение модели вместо идентификатора. - person Simon Fakir; 12.08.2016

Вы можете попробовать сделать, как было предложено, но с вводом текста при выборе, например

<input type="text" 
       ng-model="myModel" 
       typeahead="o as o.text for o in options | filter:$viewValue | limitTo:5" 
       typeahead-editable="false" 
       typeahead-on-select="model=$item.value"
/>

Это гарантирует, что текст или метка будут отображаться, но базовое значение будет изменено.

person domenicr    schedule 26.02.2015
comment
это предполагает, что вы можете быть в некоторой степени свободны в выборе формата, который вы ng-model будете использовать. При ограничении простыми типами, как в `ng-model=item.value, это не будет работать, если вы не проксируете его каким-либо образом. - person jusopi; 12.06.2015
comment
Вы должны упомянуть, что model не является чем-то вроде myModel. Я использую ваш метод, но model означает привязку к new model и использовал его в контроллере. каким-то образом ng-модель по-прежнему является форматом объекта. - person praHoc; 16.10.2017

Вот сокращенный форматер для всех, кто использует lodash или подчеркивание:

function formatTypehead(array,id){
  var o = _.find(array,{id:id});
  return (o?o.displayName || id:id);
}

и HTML:

<input  type="text" 
  uib-typeahead="s.id as s.displayName for s in companies | filter:$viewValue | limitTo:8"
  typeahead-input-formatter="formatTypehead(companies, $model)"
  ng-model="model.company"
  >
person Simon Fakir    schedule 12.08.2016

Ну, пока я нашел возможное решение через директивы.

HTML

<div my-autocomplete my-autocomplete-source="element" my-autocomplete-model="obj[element.model]"></div>

ДИРЕКТИВА

app.directive('myAutocomplete', function() {
    return {    
        restrict: 'A',
        replace: true,
        template: '<input type="text" name="{{myAutocompleteSource.model}}" placeholder="{{myAutocompleteSource.label}}" ng-model="selected" typeahead="o as o.text for o in myAutocompleteSource.options | filter:$viewValue | limitTo:5" typeahead-editable="false" />',
        scope: {
            myAutocompleteSource: '=',
            myAutocompleteModel: '='
        },
        controller: function($scope) {
            $scope.selected = null;
            $scope.$watch('selected', function() { 
                $scope.myAutocompleteModel = ($scope.selected && 'value' in $scope.selected) ? $scope.selected.value : null; 
            });
        }
    };  
});

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

person Matteo Piazza    schedule 30.10.2013

для меня это:

uib-typeahead="o as o.RagioneSociale for o in main.getLocation($viewValue)"

вместо:

typeahead="o as o.RagioneSociale for o in main.getLocation($viewValue)"

было действительно полезно

у меня был json, сделанный следующим образом:

[{"RagioneSociale":"Politi Real Estate sas","IDAnagrafica":"2516"},{"RagioneSociale":"COND METROPOLITAN","IDAnagrafica":"4325"}]


Model: {{asyncSelected | json}}
<input type="text" ng-model="asyncSelected" uib-typeahead="o as o.RagioneSociale for o in main.getLocation($viewValue)" typeahead-loading="loadingLocations" typeahead-no-results="noResults" class="form-control">

и это закончилось чем-то вроде раскрывающегося меню только со значением RagioneSociale и моделью, в которой я могу видеть текст и идентификатор и печатать их с помощью обычного {{asyncSelected}}

person Gio Venice    schedule 24.10.2016