2015-05-08 2 views
0

Я реализую вход, который позволяет выбирать несколько значений в качестве тегов. Я работаю с angular-ui-bootstrap-typeaheadAngular typeahead response error

Следующий пример с фиктивными данными работает отлично:

enter image description here

вид:

<script type="text/ng-template" id="form_field_ref"> 
<div class='container-fluid' ng-controller="typeHeadTestCtrl"> 
    <input type="text" ng-model="selected" typeahead="x.formatted_address for x in dynamicSearch($viewValue, field.displayName)" class="form-control" typeahead-on-select='onSelect($item, field)'> 
</div> 
</script> 

часть контроллера:

 $scope.getLocation = function(val) { 
      return $http.get('http://maps.googleapis.com/maps/api/geocode/json', { 
      params: { 
       address: val, 
       sensor: false 
      } 
      }).then(function(response){ 
      console.log(response); 
      return response.data.results.map(function(item){ 
       console.log(item); 
       //items attribute=> address_components, formatted_address, place_id.... 
       return item; 

      }); 
      }); 
     }; 

Но когда я попробуйте подключиться к моим фактическим данным, я получаю следующее сообщение об ошибке:

TypeError: Cannot read property 'length' of undefined 
at ui-bootstrap-tpls.js:3637 
at processQueue (angular.js:13170) 
at angular.js:13186 
at Scope.$eval (angular.js:14383) 
at Scope.$digest (angular.js:14199) 
at Scope.$apply (angular.js:14488) 
at $$debounceViewValueCommit (angular.js:20944) 
at $setViewValue (angular.js:20916) 
at HTMLInputElement.listener (angular.js:19632) 
at HTMLInputElement.eventHandler (angular.js:3011) 

Вот код, который не удается:

вид:

<input type="text" ng-model="selected" typeahead="x.theVal for x in dynamicSearch($viewValue, field.displayName)" class="form-control" typeahead-on-select='onSelect($item, field)'> 

части контроллера:

dynamicSearch() готовит то, что данные для запроса по вызову of getDbRefDocs():

 $scope.dynamicSearch = function(searchTerm, name) { 
      var allowed = {}; 
      var classString = ""; 
      allowed = datamodel.classes[$routeParams.class].attribute[name].allowed; 
      for (key in allowed){ 
      classString = classString + key + "|"; 
      } 
      //remove last pipeline 
      classString = classString.slice(0, -1); 
      $scope.getDbRefDocs(searchTerm, name, classString); 
     }; 

     $scope.getDbRefDocs = function(searchTerm, name, classString) { 
      var url = '/api/v2/docs/' + classString; 
      return $http.get(url, { 
      params: { 
       '>displayName': searchTerm, 
       count: 5      
      } 
      }).then(function(response){ 
      var data = response.data.data; 
      console.log('data:'+data); 
      var requested = []; 
      angular.forEach(data.requested, function(searchTerm, k, o) { 
       requested.push(createDBOifNecessary(searchTerm)); 
      }); 
      $scope.item=[]; 
      $scope.options=[]; 
      $scope.options[name] = []; 
      for (key in requested) { 
       if (requested.hasOwnProperty(key)) { 
       //This is the storing value 
       //console.log(requested[key].cid); 
       //this is the display value 
       //console.log(requested[key].attributes.displayName[0]); 
       $scope.options[name][key] = requested[key].attributes.displayName[0]; 
       $scope.item.push({ 
        'theName':requested[key].attributes.displayName[0], 
        'theVal':requested[key].cid 
       }); 
       } 
      } 
      console.log('item:'+$scope.item); 
      return $scope.item; 

      }); 
     }; 

Этот последний console.log корректно возвращает требуемые данные!

Для чего я смог прочитать проблему, связан с обещанием запроса сервера ... но я застрял!

ответ

0

Я не уверен, что случилось, потому что я получал ожидаемые данные.

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

Вместо я добавил триггер события, который обновляет массив атрибут машинописный считывает из и теперь он работает нормально , Также требуется typeahead-wait-ms, потому что ответ моего сервера составляет от 20 до 30 мс, поэтому для обеспечения безопасности я установил его на 200 мс.

рабочий код:

вид: отображает значения массива "элемента" (item.theName == x.theName)

<input type="text" ng-model="selected" typeahead="x.theName for x in item" ng-change="dynamicSearch($viewValue, field.displayName)" typeahead-wait-ms="1000" class="form-control" typeahead-on-select='onSelect($item, field)'> 

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

На нг-изменения -> dynamicSearch() => определить, какой запрос данных и вызвать запрос

$scope.dynamicSearch = function(searchTerm, name) { 
    var allowed = {}; 
    var classString = ""; 
    allowed = datamodel.classes[$routeParams.class].attribute[name].allowed; 
    for (key in allowed){ 
    classString = classString + key + "|"; 
    } 
    classString = classString.slice(0, -1); 
    $scope.getDbRefDocs(searchTerm, name, classString); 
}; 

По вызову getDbRefDocs () => Я определить значение массива «пункт»

$scope.getDbRefDocs = function(searchTerm, name, classString) { 
    var url = '/api/v2/docs/' + classString; 
    $http.get(url, { 
    params: { 
     '>displayName': searchTerm, 
     count: 5      
    } 
    }).then(function(response){ 
    var data = response.data.data; 
    var requested = []; 
    angular.forEach(data.requested, function(searchTerm, k, o) { 
     requested.push(createDBOifNecessary(searchTerm)); 
    }); 
    $scope.item=[]; 
    for (key in requested) { 
     if (requested.hasOwnProperty(key)) { 
     $scope.item.push({ 
      'theName':requested[key].attributes.displayName[0], 
      'theVal':requested[key].cid 
     }); 
     } 
    } 
    }); 
}; 

Когда элемент выбран из доступных опций «пункта» => машинописных-на-выберите = «onSelect ($ пункт, поле)» => Я храню item.theVal:

$scope.onSelect = function (item, field) { 
     field.theValues[field.theValues.length] = item.theVal; 
    };