Ng-table: tableParams.reload () não recarrega os dados do filtro

Criado em 27 jan. 2014  ·  30Comentários  ·  Fonte: esvit/ng-table

estou usando tableParams.reload () (e params.total (filterData.length)) que recarrega a tabela com os novos dados externos, mas as seleções nos filtros "selecionar" e "selecionar múltiplos" não mudam. tableParams.reload () deve chamar as funções "filter-data" novamente, não? existe outra maneira de fazer isso?

Comentários muito úteis

Meus dados são carregados com sucesso no DOM, mas quando eu busco os dados do servidor e desejo atualizar a tabela ng por tableParams.reload (), não está refletindo o resultado, mas quando clico em classificação ou paginação, está refletindo o resultado.
que problema pode ser esse?

Todos 30 comentários

Olá. Em primeiro lugar - obrigado pelo projeto.
Eu tenho o mesmo problema. Preciso atualizar os filtros com dados obtidos de um servidor, mas não tenho ideia de como acionar a função de dados de filtro.

Descobri que se você declarar seus dados diretamente na função getData, eles parecem atualizar a tabela.
Então ..... getData: function ($ defer, params) {
var data = $ scope.yourdata;
var OrderData = ...............................
}

Meus dados são carregados com sucesso no DOM, mas quando eu busco os dados do servidor e desejo atualizar a tabela ng por tableParams.reload (), não está refletindo o resultado, mas quando clico em classificação ou paginação, está refletindo o resultado.
que problema pode ser esse?

Eu gostaria de apoiar o que

Tive o mesmo problema com @developersatish.
Aguarde uma resolução para este problema.

Olá a todos. Recentemente comecei a usar o ngTable. Estou tendo um problema semelhante, especialmente com ngTables aninhados e recarregando dados separados dos dados pai. aqui está uma ideia rápida:

controlador pai:

var parentData = [...];

$ scope.details = -1

$ scope.showDetails = function (id) {
$ scope.details = id;
};

// ngTable ////////
$ scope.tableParams = new ngTableParams ({
página: 1, // mostra a primeira página
contagem: 10, // contagem por página
Ordenação: {
id: 'asc' // classificação inicial
}
}, {
total: parentData.length, // comprimento dos dados
getData: function ($ defer, params) {
// use filtro angular embutido
var OrderData = params.sorting ()?
$ filter ('orderBy') (parentData, params.orderBy ()):
parentData;
$ defer.resolve (OrderData.slice ((params.page () - 1) * params.count (), params.page () * params.count ()));
}
});

no html eu tenho um ng-click para enviar o id para isso e alterar o escopo de detalhes.

Controlador filho (tabela secundária relacionada ao primeiro controlador):

var childData = [...];

$ scope. $ parent. $ watch ('details', function () {
console.log ("você fez isso aqui");
$ scope.tableParams2.reload ();
});

// filho ngTable ////////
$ scope.tableParams2 = new ngTableParams ({
página: 1, // mostra a primeira página
contagem: 10, // contagem por página
Ordenação: {
id: 'asc' // classificação inicial
}
}, {
total: childData.length, // comprimento dos dados
getData: function ($ defer, params) {
// use filtro angular embutido
var OrderData = params.sorting ()?
$ filter ('orderBy') (childData, params.orderBy ()):
childData;
$ defer.resolve (OrderData.slice ((params.page () - 1) * params.count (), params.page () * params.count ()));
},
$ escopo: {$ dados: {}}
});

Posso ver a mudança quando clico, mas minha tabela filho não está atualizando. Não tenho certeza se isso ajuda, mas acho que está relacionado.

Oi,
Também estou tendo os mesmos problemas que @developersatish. Os dados da tabela só são atualizados depois de classificar ou filtrar a tabela. Existe alguma solução para este problema?

Eu tenho um problema semelhante.

Em um evento de clique, começo a recuperar dados de um servidor (várias chamadas).
Portanto, tenho um loop for e nele tenho solicitações GET e armazeno os resultados que retornam em uma variável de escopo que quero plotar em uma tabela assíncrona.

No entanto, com o clique, instancio minha tabela da seguinte forma:

`$scope.tableParams = new ngTableParams({
        page: 1, // show first page
        count: 10, // count per page
        sorting: {
            Country: 'asc' // initial sorting
        }
    }, {
        total: $scope.continentTableData.length, // length of data
        getData: function($defer, params) {
            for (var i = 0; i < numberOfCountries; i++) {
                try {
                    var country = $("path[class*=" + $scope.currentContinentCountries[i].toUpperCase() + "]")[0].__data__.properties.name;
                    MapService.getInfographicsData(2013, country, function(infrographicsData) {
                        counter++;
                        // debugger;
                        var cpi = infrographicsData[0].data.CPI;
                        var trace = infrographicsData[1].data;
                        var countryName;

                        if (cpi == null) {
                            countryName = trace.Ref_Country;
                        } else {
                            countryName = cpi.Country;
                        }

                        var joinedData = {
                            Country: countryName,
                            Cpi: cpi,
                            Trace: trace
                        }
                        $scope.continentData.push(joinedData);

                        $scope.continentTableData = $scope.continentData;

                        // if (counter==numberOfCountries-1) {
                        //     console.log("tier");
                            $timeout(function() {
                            // update table params
                            params.total($scope.continentTableData.length);
                            // set new data
                            console.log("new data set");
                            $defer.resolve($scope.continentTableData);
                        }, 1500);
                        // };

                    });
                } catch (e) {
                    // console.log(e);
                    continue;
                }                    
            }

            // $scope.$apply();
        }
    });`

como no exemplo ngTable com ajax. No entanto, nada é mostrado na tabela (getData nunca é chamado).

Se eu clicar em "atualizar" tableParams, a tabela começa a carregar tudo, exceto que cada item é duplicado.

Qualquer ideia?

@developersatish Consegui refletir novos dados do servidor copiando a funcionalidade anexada aos botões de paginação.

$scope.tableParams.count(1);

Coloquei isso no retorno de chamada do meu pedido.

myRequest().then(function(response) {
    $scope.data = response;
    $scope.tableParams.total($scope.data.length);
    $scope.tableParams.count(1);
});

Editar:

Em minha postagem original, o 1 em $scope.tableParams.count(1) deve ser substituído por uma variável que contém o valor definido como count em ngTableParams .
Consulte http://embed.plnkr.co/harWG3J6OlNHzbOu0e6S/preview para obter um exemplo prático.

Como este é o principal resultado da pesquisa para esse problema, incluirei o que fiz para minha solução. Eu simplesmente armazenei em meu $ scope o array de objetos {id, title} que é usado como argumento para defer.resolve na função de dados de filtro. (pode estar / provavelmente está vazio inicialmente.) Você pode então atualizar esse array a qualquer momento e as alterações serão refletidas na seleção do filtro. Então, eu o atualizo quando minha chamada ajax traz de volta a resposta do servidor.

Também no meu caso, o conjunto de dados da tabela se expande (é aumentado) conforme o usuário expande o intervalo de pesquisa. Isso requer que eu também modifique (aplique uma diferença) os filtros selecionados.

Tentei fazer isso, mas não funcionou. Você pode colar seu exemplo de trabalho?

Ei pessoal,
Tenho o mesmo problema que @almaplayera , tenho um cenário parecido com

1. Os dados do filtro usados ​​no menu suspenso vêm do serviço

2. E para atualizar os mesmos dados, eu tenho uma seção de onde o usuário pode adicionar novas entradas / atualizar as existentes.

3. Depois de adicionar / atualizar as entradas da seção adicionar / editar dados de filtro para o menu suspenso, esse menu suspenso deve ser atualizado assim que a tabela estiver recarregando.

Estou fazendo isso para que os dados da minha empresa filtrem os dados -

screen4ngtable

Depois disso, chamei o método getCompany em dados-filtro da minha visão -

screen5ngtable

Alguém pode sugerir alguma solução para atualizar meus dados de filtro com os dados recentes do serviço? Ou fornecer alguns exemplos para casos de uso semelhantes.

@esvit : eu tentei obter meus dados no retorno de chamada getData em ngTablePrams e vinculei-os a $ scope depois disso, tentei passar a mesma variável para filter-data em view algo como @israelidanny sugerido em https://github.com/esvit / ng-table / pull / 342, mas isso também não está funcionando para mim. :(

PS: estou fazendo tableParams.reload (); após adicionar e editar.

Eu não tenho mais meu código quando mudei da mesa antes de comprometer qualquer coisa. No entanto, indo de memória:

As funções de filtro (sua função getCompany) são invocadas apenas uma vez no init da tabela. Portanto, você deve aplicar as alterações ao array de dados resolvido sempre que houver alterações de registro e o angular aplicará essas alterações ao dom.

$scope.company_filter = [];

$scope.getCompanyFilter = function(data) {
  var def = $q.defer();
  companyService.getAll().success(function(response) {
    $scope.updateCompanyFilter(response.data);
    def.resolve($scope.company_filter);
  });
  return def;
};

$scope.updateCompanyFilter = function(data) {
  $scope.company_filter.length = 0;
  for (i in data) {
    $scope.company_filter.push({
        'id': data[i].id,
        'title': data[i].name
    });
  }
};

// Then wherever you refresh your table data, just call updateCompanyFilter(data).
// Or you could micro manage the filter array when you do adds/deletes instead of reseeding it every time.

<td ... filter-data="getCompanyFilter($column)" >

Mais uma vez, posso estar errado, pois já se passaram alguns meses.

Este problema foi corrigido na versão mais recente do ng-table?

Alguém poderia fornecer um exemplo de código

Eu não acho que seja.

Agora, eu não acho que seria muito difícil fazer o
função controller.loadFilterData disponível para ser chamada a partir do
tablParams. Você poderia então chamar isso quando as listas mudassem em
seu aplicativo.

C

Na sexta-feira, 19 de junho de 2015 às 6h59, rachithaShetty [email protected]
escreveu:

Este problema foi corrigido na versão mais recente do ng-table?

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/esvit/ng-table/issues/186#issuecomment -113384084.

: +1: @kyleboyle : sua solução é

Parece que a resolução para esse problema (solicitação pull 403: https://github.com/esvit/ng-table/pull/403) foi mesclada na v0.4.2, mas a alteração feita foi revertida desde então.

Na linha 549 de alteração de ng-table.js

$ scope. $ watch ('params. $ params', function (newParams, oldParams) {
para
$ scope. $ watch ('[params. $ params, params.data]', function (newParams, oldParams) {

Isso resolveu o problema com os dados sendo atualizados, mas a tabela não era atualizada para processar as alterações.
Parece que esse bug foi reintroduzido neste commit: https://github.com/esvit/ng-table/commit/9189e987fba90b07ffc6b17c982961ad65edf725#diff -6aca4bc06732c0635eb9860dc6cd040fL490

Infelizmente $watch 'ing params.data causa problemas em certas circunstâncias:

quando os elementos dentro de params.data são complexos envolvendo referências circulares, $watch 'ing _by value_ causa uma exceção de estouro de pilha quando angular.copy cria um clone profundo.

Acredito que uma versão mais recente de angular.copy corrige esse problema específico, mas ainda é uma má ideia assistir params.data _by value_ por motivos de desempenho.

@kyleboyle Este código funciona perfeitamente! Obrigado! E adicionar a função inArray pode filtrar as duplicatas.

    $scope.manufacturer_filter = [];
    $scope.getManufactFilter = function(column){
        var def = $q.defer();
        ResourseAPI.query(function(data){
            $scope.updateManufactFilter(data.devices);
            def.resolve($scope.manufacturer_filter);
        });
        return def;
    };
    $scope.updateManufactFilter= function(data) {
        var arr = [];

        angular.forEach(data, function (item) {
            if (inArray(item.manufacturer, arr) === -1) {
                arr.push(item.manufacturer);
                $scope.manufacturer_filter.push({
                    'id': item.manufacturer,
                    'title': item.manufacturer
                });
            }
        });
    };

    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;
    };

@kyleboyle Sua solução é ótima.
Alguém sabe se eles poderiam implementar algo semelhante, mas usando ng-table-dynamic?
Eu carrego colunas dinamicamente por javascript.

Exemplo:

var column = {
    title: 'Example',
    sortable: 'example',
    filter: 'example',
        filterData: .....,
    show: true,
    field: 'example'
};

O que deve definir a propriedade filterData? Ou existe outra maneira de recarregar os filtros de dados?

Existem muitas maneiras diferentes de especificar a matriz que o filtro de seleção usará como fonte de dados. Cada um desses métodos se aplica a ng-table e ng-table-dynamic .

Talvez o exemplo de código a seguir possa ajudá-lo a descobrir algo?

http://codepen.io/christianacca/pen/JdqjxB?editors=101

Boa amostra, mas não consigo encontrar a solução para o meu problema. Em todos os exemplos, os dados são carregados apenas uma vez (sincronizado ou assíncrono), mas não são recarregados.

Um exemplo do que recebo é:
Tenho duas colunas: Países e cidades, cada uma com um filtro.
Assim:

  • Quando o filtro de país é nulo, solicita ao servidor todas as cidades.
  • Quando o filtro de país é selecionado, pergunte ao servidor a única cidade que o país se aplica e atualize a coluna filterData of cities.

Está entendido? Desculpe pelo meu Inglês.

Obrigado pela resposta.

@kyleboyle nenhuma dessas soluções funciona para mim (eu nem estou fazendo nenhuma filtragem) e estou interpretando como um sinal de baixa qualidade de código que a tabela não é atualizada quando os dados subjacentes o fazem. Para qual solução de mesa Angular você mudou?

@BartoGabriel Acho que o que você está tentando fazer é possível. Um cara com quem trabalhei resolveu o problema criando seu próprio modelo de filtro que fazia exatamente o que você disse. Ele substituiu o modelo select.html de maneira semelhante ao seguinte exemplo: http://codepen.io/christianacca/pen/xGeWGX?editors=101

Desculpe, não posso ser mais útil, apenas ganhei tempo!

Ah, a propósito, o cara que mencionei, ele usou o ui-select2

@christianacca obrigado pela ajuda. Foi muito útil.
Quando eu tiver a solução, vou compartilhar.

Legal :-)

Oi pessoal, minha solução está totalmente errada ou @kyleboyle é apenas uma alternativa melhor?

@telwing sua solução não funcionou para mim, mas, novamente, a de @kyleboyle também não

Eu também estou tendo os mesmos problemas que @ developersatish.i também tentei definir a contagem de tableParams, mas minha função getdata apenas no carregamento da página enquanto filtra os dados por lista suspensa, não é possível chamar esta função

$ scope.tableParams = new ngTableParams ({
página: 1, // mostra a primeira página
contagem: 8, // contagem por página
Ordenação: {
LastSeen: 'desc' // classificação inicial
},
filtro: {
Nome do paciente: '', // filtro inicial
},
}, {
filterSwitch: true,
getData: function ($ defer, params) {
// use filtro angular embutido
var filterData = params.filter ()?
$ filter ('filter') ($ scope.items, params.filter ()):
$ scope.items;

        var orderedData = params.sorting() ?
                            $filter('orderBy')(filteredData, params.orderBy()) : filteredData;
        params.total(orderedData.length); // set total for recalc pagination
        $scope.tableParams.count(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));



    }
});
Esta página foi útil?
0 / 5 - 0 avaliações