7

我正在尝试使用我设置的 REST 资源让 Angular UI 引导输入提前。但我不确定如何让它与它的异步特性一起工作。

目前,我已经改编了 Angular UI Bootstrap 给出的示例。

所以我的 html 看起来像这样,调用 getLibs() 来获取 typeahead 下拉列表的列表。

<div class='container-fluid' ng-controller="TypeaheadCtrl">
    <pre>Model: {{selected| json}}</pre>
    <input type="text"  typeahead="lib.name for lib in getLibs($viewValue)" active='active' ng-model="selected" typeahead-min-length='3' >
</div>

我的资源看起来像这样:

angular.module('LibraryLookupService', ['ngResource']).factory('Library', 
    function($resource){
        return $resource(   "../../api/seq/library/?name__icontains=:searchStr" , {} , 
        {   'get':    {method:'GET'},
            'query':  {method:'GET', params: {} ,  isArray:false },
        }
    )
}

);

我的控制器看起来像这样(我猜它在这里我做错了):

function TypeaheadCtrl($scope , Library){

    $scope.selected = undefined;
    $scope.active = undefined ;

    $scope.libs = [{name:'initial'} , {name:"values"}];

    $scope.getLibs = function(viewValue){
        console.log("value:", viewValue);
        if (viewValue.length > 3 ) { 
            var return_vals =  Library.query({searchStr:viewValue},  function() {
                $scope.libs = return_vals.objects ; 
                console.log("here", $scope.libs) ; 
                }) ;
            }
        return $scope.libs
    }
}

据我了解,预输入菜单是从 getLibs() 函数的返回值填充的。当调用 getLibs() 时,它正在查询 REST 接口,但最初返回一个空值。这是由提供给 Library.query() 方法的函数填充的,这是在从 REST 请求返回数据之后完成的。

这基本上意味着菜单的更新时间比我想要的晚。我输入“3456”,它会填充对 REST 接口的“345”查询结果。

从 Library.query() 函数返回响应时,如何更新菜单?我这样做对吗?

4

6 回答 6

7

我是这样解决的:

我的工厂:

angular.module('frontendApp')
  .factory('PersonService', function($resource) {
    // Service logic
    // ...

    return $resource(APP_CONFIG.prefixURLRest + '/person', {
      //id: '@id'
    }, {
      search: {
        method: 'POST',
        isArray: true
      }
    });

  });

我的控制器

...
$scope.searchTypeAhead = function(name) {
  var person = {
    'name': name
  };

  return PersonService.search(person)
    .$promise.then(function(response) {
      return response;
    });
};
于 2015-02-20T21:25:03.367 回答
6

http://angular-ui.github.io/bootstrap/中的 typeahead 指令依赖于 promise API ( $q) 以处理异步建议。问题$resource在于它用于缺乏对承诺的支持(它是最近才在不稳定的分支中添加的)。所以你在这里有两个解决方案:

1) 与承诺一起工作的中继$http(IMO $http 对于大多数自动完成案例来说应该绰绰有余)。2) 切换到最新的不稳定版本的 AngularJS 并使用 Promise。

$resource 的目的是使用完整的 HTTP 动词集来定位 RESTful 端点。如果你只想查询数据,你最好还是使用 $http 来达到这个目的。

有一个关于 typeahead 的类似问题,其答案涵盖了它的用法$httpHow to tie angular-ui's typeahead with a server via $http for server side optimization?

于 2013-04-10T17:26:43.823 回答
2

如果您不想使用 $http(因为您想重用现有的 $resource),或者不想切换到不稳定的分支,您可以将对 $resource 的调用包装在一个 Promise 中。这有点冗长,但它确实有效。快速示例(使用 AngularJS 1.0.6):

$scope.getLibs = function(input){
    var defer = $q.defer();
    if (input){
        Library.query({searchStr:viewValue},
            function(data,headers){
                if (!$scope.$$phase){ //check if digest is not in progress
                    $rootScope.$apply(function(){
                        defer.resolve(data);
                    });
                } else {
                    defer.resolve(data);
                }
            },
            function(response){
                if (!$scope.$$phase){
                    $rootScope.$apply(function(){
                        defer.reject('Server rejected with status ' + response.status);
                    });
                } else {
                    defer.reject('Server rejected with status ' + response.status);
                }
            });
    } else {
        if (!$scope.$$phase){
            $rootScope.$apply(function(){
                defer.reject('No search query ');
                $log.info('No search query provided');
            });
        } else {
            defer.reject('No search query ');
            $log.info('No search query provided');
        }
    }
    return defer.promise;
};
于 2013-04-29T11:33:28.923 回答
2

只需从资源中返回 $promise:

UsuarioResource.query().$promise
于 2016-09-14T23:49:49.347 回答
1

如果您使用的是 Angular 1.2.13(或附近的某个地方,还没有全部测试过)

请参阅:https ://stackoverflow.com/a/21888107/484802

为我工作。

于 2014-02-19T17:41:22.723 回答
1

此代码适用于 angular 1.6 和最新的 ui 的 angular-bootstrap3-typeahead

GET /cities?name="somename" 的 api 端点响应:

[
    {name: "somename", zipcode: 11111, etc: ""},
    {name: "somename", zipcode: 22222, etc: ""},
    {name: "somename", zipcode: 33333, etc: ""}
]

$资源工厂:

getCities: {
    url: '/cities',
    method: 'GET
}

控制器:

$scope.getCities = function(name) {
    return City.getCity({
        name: name
    }).$promise.then(function(response) {
        return response;
    });
};

看法:

<input ng-model-control data-ng-model="city" uib-typeahead="city.name for city in getCities($viewValue)" />

似乎此解决方案不适用于过滤,请参阅https://github.com/angular-ui/bootstrap/issues/1740

于 2017-05-09T10:44:34.580 回答