当前位置: 首页 > 知识库问答 >
问题:

如何从异步调用填充ng表上的选择过滤器

湛同
2023-03-14

如何使用ajax/json填充包含“选择”过滤器的ng表?

Plunk显示问题:http://plnkr.co/Zn09LV

我正在努力掌握AngualrJS和ng表扩展,虽然我可以得到一些带有工作过滤器的好表,例如当我使用javascript中定义的静态数据时——一旦我尝试将真实数据加载到表中,我就遇到了一个障碍。

ng表的主体填充正确,只要我只使用文本过滤器,一切似乎都正常:

        <td data-title="'Name'" filter="{ 'Name': 'text' }" sortable="'Name'">
            {{user.Name}}
        </td>

很好用。

但是,如果我更新它以使用选择过滤器:

        <td data-title="'Name'" filter="{ 'Name': 'select' }" sortable="'Name'"  filter-data="Names($column)">
            {{user.Name}}
        </td>

我遇到了一个同步问题,因为在数据从服务器返回之前,总是先计算Names变量。(在向服务器发送请求之前,可能会对名称varibale进行评估。)这意味着我得到了一个空的过滤器列表。

一旦数据从服务器返回,我似乎找不到更新select筛选器的方法。重新运行最初创建过滤器列表的代码似乎没有任何效果-我不知道如何触发ng表重新检查其过滤器,以便不读取更新的变量。我也无法找到一种方法来推迟对变量的求值,直到异步调用完成。

对于我的javascript,我几乎使用了ng table GitHub页面中的示例ajax代码,并在其中添加了select过滤器的示例代码。

    $scope.tableParams = new ngTableParams({
        page: 1,            // show first page
        count: 10,          // count per page
        sorting: {
            name: 'asc'     // initial sorting
        }
    }, {
        total: 0,           // length of data
        getData: function($defer, params) {
            // ajax request to api
            Api.get(params.url(), function(data) {
                $timeout(function() {
                    // update table params
                    var orderedData = params.sorting ?
                    $filter('orderBy')(data.result, params.orderBy()) :
                    data.result;
                    orderedData = params.filter ?
                    $filter('filter')(orderedData, params.filter()) :
                    orderedData;

                    $scope.users = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());

                    params.total(orderedData.length); // set total for recalc pagination
                    $defer.resolve($scope.users);
                }, 500);
            });
        }
    });

    var inArray = Array.prototype.indexOf ?
    function (val, arr) {
        return arr.indexOf(val)
    } :
    function (val, arr) {
        var i = arr.length;
        while (i--) {
            if (arr[i] === val) return i;
        }
        return -1
    };
$scope.names = function(column) {
    var def = $q.defer(),
        arr = [],
        names = [];
    angular.forEach(data, function(item){
        if (inArray(item.name, arr) === -1) {
            arr.push(item.name);
            names.push({
                'id': item.name,
                'title': item.name
            });
        }
    });
    def.resolve(names);
    return def;
};

我尝试过添加额外的$q.defer(),并包装初始数据get后面的$scope。名称起作用——但我对promise和延迟的理解还不足以让任何事情都起作用。

GitHub上有一些注释表明这是ng表中的一个错误,但我不确定是这样还是我只是在做一些愚蠢的事情。

https://github.com/esvit/ng-table/issues/186

非常感谢关于如何进行的指示

-凯恩-

共有3个答案

许庆
2023-03-14

这对我很有用:

超文本标记语言:

<td data-title="'Doc type'" filter="{ 'doc_types': 'select' }" filter-data="docTypes()" sortable="'doc_types'">
    {{task.doc_type}}
</td>

AngularJS:

$scope.docTypes = function ($scope) 
{
    var def = $q.defer();
    //var docType = [
    //    {'id':'4', 'title':'Whatever 1'},
    //    {'id':'9', 'title':'Whatever 2'},
    //    {'id':'11', 'title':'Whatever 3'}
    //];

    // Or get data from API.
    // Format should be same as above.
    var docType = $http.get('http://whatever.dev', {
        params: { param1: data1 }
    });

    //Or with Restangular 
    var docType = Restangular.all('/api/doctype').getList();

    def.resolve(docType);
    return def;
};
谭安翔
2023-03-14

您可以通过自定义过滤器实现这一点:

ngtable上标准选择过滤器的代码说:

<select ng-options="data.id as data.title for data in column.data"
    ng-model="params.filter()[name]"
    ng-show="filter == 'select'"
    class="filter filter-select form-control" name="{{column.filterName}}">
</select>

调用此数据时,需要传递:筛选数据=“名称($column)”,ngtable负责为您获取数据。我不知道为什么这对外部资源不起作用。正如你所指出的,我打赌这与$栏和promise有关。

为了避免这种情况,我在代码中做了一个快速的变通。编写自己的选择过滤器模板,如:

<select id="filterTest" class="form-control" 
    ng-model="tableParams.filter()['test']" 
    ng-options="e.id as e.title for e in externaldata">
</select>

在控制器中获取此外部数据:

$scope.externaldata = Api.query(); // Your custom api call

它工作得很好,但我的数据上确实有一个id,所以不需要名称函数。

我知道这个解决方案不是最优的。让我们看看是否有人在这里写了比这个“变通方法”更多的东西,并启发我们。甚至esvit有时也在这里;)

陈琪
2023-03-14

我有一个类似但稍微复杂一点的问题。我希望能够动态更新列表(滤镜),这似乎是完全可行的,因为它们应该只在$作用域变量中。基本上,我期望,如果我有$scope.filterOptions = [];,那么我可以设置filter-data="filterOptions"并且对该列表的任何更新都将自动反映。我错了。

但我找到了一个我认为很好的解决方案。首先,您需要重写ngTable select filter模板(如果您不知道如何做,则需要使用$templateCache,需要重写的键是'ng-table/filters/select.html')。

在普通模板中,您会发现类似这样的内容,即$column.data中的数据的data.id as data.title,而问题是$列。数据是一个固定值,在更新$范围时不会更改。过滤器选项。

我的解决方案是只将$range键作为filter-data传递,而不是传递整个选项列表。因此,我将传递filter-data="filterOptions"而不是filter-data="'filterOptions'",然后在模板中添加一个小的更改,例如:ng-选项="data.id作为{{$column.data}}"中数据的data.title。

显然,这是对select过滤器工作方式的重大更改。在我的例子中,这是一个只有一个表的非常小的应用程序,但你可能会担心这样的更改会破坏你的其他选择。如果是这种情况,您可能希望将此解决方案构建到自定义筛选器中,而不是只覆盖“select”。

 类似资料:
  • 问题内容: 我希望解决三个问题… 在我的应用程序页面中,我有一个选择州,另一个选择县。对于州,我有: 数据: 对于我的县,请选择: 数据: 这是我的: 因此,如您所见,我在州选择上使用,在县选择上使用,在县数据集中已设置了相应的州ID 。 我想做几件事: 隐藏选择的县,直到选择了一个州。 选择州后,按选定的/ 过滤县选择选项 筛选由第一,然后由。 我还没有看到一个方法来设置到或过滤器由一个数字,而

  • 问题内容: 我一直在努力寻找例子,但根本找不到任何东西。我唯一知道的是我可以使用http模块来获取数据。这是我当前正在执行的操作,但它是使用Knockout编码的。有人可以给我一些有关如何使用AngularJS重新编码此功能的建议吗? 的HTML Java脚本 问题答案: 正确的方法是使用指令。HTML看起来像这样。 JavaScript: 您还需要确保Angular在html上运行并且模块已加载

  • 问题内容: 我有一个表格(“场地”),其中存储了志愿者可以工作的所有可能场所,每个志愿者被分配为每个场所工作一个。 我想从场所表中创建一个选择下拉列表。 现在,我可以显示分配给每个志愿者的地点,但是我希望它显示下拉框,并且已经在列表中选择了地点。 例如,将ID为7的志愿者分配给了场地编号4 我知道它将采用for或while循环的形式从场地表中拉出场地列表 我的查询是: 如何填充选择下拉框与场馆(

  • 问题内容: 好的,这是我对Ajax的第一次尝试,它使我发疯,因为我实在无法绕开它。我想做的是在第一个框中用数据库中的客户填充,然后使用customerID通过select.php脚本从数据库中选择所有车辆ID。发生的情况是“客户”框被选中,但是选择客户时什么也没有发生。 这是我的Test.php文件: 这是我的select.php文件: 我正在尝试修改本教程以使用数据库,但到目前为止我没有成功。

  • 问题内容: 我是第一次使用Selenium,对这些选项不知所措。我在Firefox中使用IDE。 当我的页面加载时,它随后通过JSONP请求获取值,并以此填充select中的选项。 我如何让Selenium等待选择中的某个选项出现后再继续? 问题答案: 我认为你应该使用 命令。如果可能,让我看看您的Selenium IDE代码。