在Typeahead(AngularJS指令)中使用getJSON返回调用过滤问题

时间:2015-01-29 15:55:27

标签: jquery ajax angularjs typeahead.js

我在Typeahead中遇到过滤功能问题。当我使用静态列表(请参阅下面的$scope.statesWithFlags)时,过滤器按预期工作,即它仅显示与输入查询匹配的结果。

$scope.statesWithFlags = [{
    'name': 'Alabama',
    'flag': '5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'
  }, {
    'name': 'Alaska',
    'flag': 'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'
  }, {
    'name': 'Arizona',
    'flag': '9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'
  }, {
    'name': 'Connecticut',
    'flag': '9/96/Flag_of_Connecticut.svg/39px-Flag_of_Connecticut.svg.png'
  }];

但是,当我使用简单的getJSON调用时,会输出完全相同的$scope.statesWithFlags结果,然后所有可能的结果都会显示出来,而过滤函数| filter:{name:$viewValue}则不会似乎工作。同样适用于limitTo:6。我是否必须明确返回响应?如果是这样,怎么样?

$scope.statesWithFlags = $.getJSON('/typeahead');

这是我正在使用的输入元素:

<input type="text" ng-model="customSelected" typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-template-url="customTemplate.html" class="form-control">

2 个答案:

答案 0 :(得分:1)

您需要设置回调函数以获取响应然后进行分配。因为$.getJSON('/typeahead')是请求对象而不是服务器的响应。

$.getJSON('/typeahead',function(response){
    //parse your response and assign it
    $scope.statesWithFlags = response;
});

P.D:当你可以jQuery角度模块时,为什么要使用$http ajax调用。

答案 1 :(得分:0)

如果上面的回答没有帮助人们在angularjs中使用$ http调用并且其api响应太大,在我的情况下它是70,000行: 我最近在angularjs应用程序中遇到了同样的问题。我在我的HTML中使用过这个: <input class="form-control" style="text-overflow: ellipsis" id="diagnosis-list" type="text" ng-model="diagnosis" typeahead="searchDiagnosis as searchDiagnosis.type_code + ' &nbsp : ' + searchDiagnosis.type_code_value for searchDiagnosis in getMatchingDiagnosisList($viewValue)" typeahead-on-select="selectDiagnosis($item)&#34;&GT;

getMatchingDiagnosisList()是在控制器中编写的,如下所示:

$scope.getMatchingDiagnosisList = function($viewValue){
      console.log("$viewValue",$viewValue);
      if($viewValue.length == 2 || $viewValue.length > 2){
        console.log("$viewValue.length",$viewValue.length);
            xService.getDiagnosticList($viewValue).then(function(response){
           $scope.searchDiagnosis = {};
          if(response.data.typeCode){
          $scope.searchDiagnosis = response.data;
        }
        else{
           $scope.searchDiagnosis = {'typeCode':[]};
        }

        }).catch(function(){
           $scope.searchDiagnosis = {'typeCode':[]};
        });  
        return $scope.searchDiagnosis.typeCode;
    }
    };

调用angularjs服务,其中包含其他API调用,如下所示:

getDiagnosticList: function(value){
        var url = URL.matchingDiagnosticList.replace("SEARCH_STRING",value)
         return $http.get(url, {
          headers: headerService.getHeader()
        }).success(function(response) {
          return response;
        });
      }

由于其余的API调用,此代码无法正常工作,因此经过大量调试后,我将控制器功能编辑为:

    $scope.getMatchingDiagnosisList = function($viewValue){
          $scope.isLoading = true;
//Whatever you return below will be taken as a parameter in getMatchesAsync() of the directive, so modify the directive accordingly
            return patientService.getDiagnosticList($viewValue);    
          };          
    };

在我的情况下,我在路径bower_components \ angular-bootstrap \ ui-bootstrap-tpls.js或bower_components \ angular-bootstrap \ ui-bootstrap.js中修改了指令getmatchesasync(),如下所示:

var getMatchesAsync = function(inputValue) {
      var locals = {$viewValue: inputValue};
      isLoadingSetter(originalScope, true);
      isNoResultsSetter(originalScope, false);
      $q.when(parserResult.source(originalScope, locals)).then(function(matchesFull) {
        //it might happen that several async queries were in progress if a user were typing fast
        //but we are interested only in responses that correspond to the current view value
        var matches = matchesFull.data.typeCode;
        var onCurrentRequest = (inputValue === modelCtrl.$viewValue);
        if (onCurrentRequest && hasFocus) {
          if (matches && matches.length > 0) {

            scope.activeIdx = focusFirst ? 0 : -1;
            isNoResultsSetter(originalScope, false);
            scope.matches.length = 0;

            //transform labels
            for (var i = 0; i < matches.length; i++) {
              locals[parserResult.itemName] = matches[i];
              scope.matches.push({
                id: getMatchId(i),
                label: parserResult.viewMapper(scope, locals),
                model: matches[i]
              });
            }

            scope.query = inputValue;
            //position pop-up with matches - we need to re-calculate its position each time we are opening a window
            //with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page
            //due to other elements being rendered
            recalculatePosition();

            element.attr('aria-expanded', true);

            //Select the single remaining option if user input matches
            if (selectOnExact && scope.matches.length === 1 && inputIsExactMatch(inputValue, 0)) {
              scope.select(0);
            }
          } else {
            resetMatches();
            isNoResultsSetter(originalScope, true);
          }
        }
        if (onCurrentRequest) {
          isLoadingSetter(originalScope, false);
        }
      }, function() {
        resetMatches();
        isLoadingSetter(originalScope, false);
        isNoResultsSetter(originalScope, true);
      });
    };