Как получить выбранное значение из директивы ng-autocomplete для контроллера

0

Я использую директиву для автоматического завершения/автоматического предложения в угловых Js, взятых из http://demo.jankuri.com/ngAutocomplete/. Он отлично работает, получая данные с сервера и фильтруя его. Но я сталкиваюсь с проблемой в выборе и использовании, которые выбирают элемент из автоматического завершения. Вот код директивы, который я использую для этого...

app.factory('ngAutocompleteService', ['$http', function($http) 
{
    var self = this;
    self.getData = function (url, keyword) {
        return $http.get(url, { query: keyword });
    };

    return self;
}])

app.directive('ngAutocomplete', ['$timeout','$filter','ngAutocompleteService', 

function($timeout, $filter, ngAutocompleteService)
 {

    'use strict';

    var keys = {
        left    : 37,
        up      : 38,
        right   : 39,
        down    : 40,
        enter   : 13,
        esc     : 27
    };

    var setScopeValues = function (scope, attrs) {
        scope.url = base_url+attrs.url || null;
        scope.searchProperty = attrs.searchProperty || 'skills';
        scope.maxResults = attrs.maxResults || 10;
        scope.delay = parseInt(attrs.delay, 10) || 300;
        scope.minLenth = parseInt(attrs.minLenth, 10) || 2;
        scope.allowOnlyResults = scope.$eval(attrs.allowOnlyResults) || false;
        scope.placeholder = attrs.placeholder || 'Search...';
    };

    var delay = (function() {
        var timer = 0;
        return function (callback, ms) {
            $timeout.cancel(timer);
            timer = $timeout(callback, ms);
        };
    })();

    return {
        restrict: 'E',
        require: '?ngModel',
        scope: true,
        link: function(scope, element, attrs, ngModel) {
            setScopeValues(scope, attrs);

            scope.results = [];
            scope.currentIndex = null;

            scope.getResults = function () {
                if (parseInt(scope.keyword.length, 10) === 0) scope.results = [];
                if (scope.keyword.length < scope.minLenth) return;

                delay(function() {
                    ngAutocompleteService.getData(scope.url, scope.keyword).then(function(resp) {
                        scope.results = [];
                        var filtered = $filter('filter')(resp.data, {skills: scope.keyword});
                        for (var i = 0; i < scope.maxResults; i++) {
                            scope.results.push(filtered[i]);
                        }
                        scope.currentIndex = 0;

                        if (scope.results.length) {
                            scope.showResults = true;
                        }
                    });
                }, scope.delay);
            };

            scope.selectResult = function (r) {
                scope.keyword = r.skills;
                ngModel.$setViewValue(r.skills);
                scope.ngModel = r.skills;
                ngModel.$render(); 
                scope.showResults = false;
            };

            scope.clearResults = function () {
                scope.results = [];
                scope.currentIndex = null;
            };

            scope.hoverResult = function (i) {
                scope.currentIndex = i;
            }

            scope.blurHandler = function () {
                $timeout(function() {
                    if (scope.allowOnlyResults) {
                        var find = $filter('filter')(scope.results, {skills: scope.keyword}, true);
                        if (!find.length) {
                            scope.keyword = '';
                            ngModel.$setViewValue('');
                        }
                    }
                    scope.showResults = false;
                }, 100);
            };

            scope.keyupHandler = function (e) {
                var key = e.which || e.keyCode;

                if (key === keys.enter) {
                    scope.selectResult(scope.results[scope.currentIndex]);
                }

                if (key === keys.left || key === keys.up) {
                    if (scope.currentIndex > 0) {
                        scope.currentIndex -= 1;
                    }
                }

                if (key === keys.right || key === keys.down) {
                    if (scope.currentIndex < scope.maxResults - 1) {
                        scope.currentIndex += 1;
                    }
                }

                if (key === keys.esc) {
                    scope.keyword = '';
                    ngModel.$setViewValue('');
                    scope.clearResults();
                }
            };
        },
        template:
        '<input type="text" class="form-control" ng-model="keyword" placeholder="{{placeholder}}" ng-change="getResults()" ng-keyup="keyupHandler($event)" ng-blur="blurHandler()" ng-focus="currentIndex = 0" autocorrect="off" autocomplete="off">' +
        '<input type="hidden" ng-model="skillIdToBeRated">'+
        '<div ng-show="showResults">' +
        '  <div ng-repeat="r in results | filter : {skills: keyword}" ng-click="selectResult(r)" ng-mouseover="hoverResult($index)" ng-class="{\'hover\': $index === currentIndex}">' +
        '    <span class="form-control">{{ r.skills }}</span>' +
        '  </div>' +
        '</div>'
    };
}]);

Я не могу получить значение, которое выбирается функцией ng-click = "selectResult (r)". Значение отображается в текстовом поле, но не попадает в контроллер.

Теги:

2 ответа

0
Лучший ответ

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

в HTML

<div ng-controller="Cntrl as cntrl">
  <ng-autocomplete ng-model="cntrl.selectedValue"  url="url" search-property="keyword" max-results="10" delay="300" min-length="2" allow-only-results="true"></ng-autocomplete>
</div>

в JavaScript

app.controller('Cntrl', function($scope, $http) {
    var self = this;
    self.selectedValue = '';

    $scope.getSelectedValue = function(){
    console.log(self.selectedValue);
    }
});

Надеюсь, это может вам помочь.

0

Я столкнулся с тем же вопросом. Я просто просмотрел свойство из атрибута details в входе ng-autocomplete, и он работает очень хорошо.

$scope.$watch(function() {
  return vm.location_result;
}, function(location) {
    if (location) {
       vm.location_list.push(location);
       vm.location = '';
    }
});

Пример скрипта: http://jsfiddle.net/n3ztwucL/

GitHub Gist: https://gist.github.com/robrothedev/46e1b2a2470b1f8687ad

Ещё вопросы

Сообщество Overcoder
Наверх
Меню