Question

Good evening fellows. I'm trying to build an bootstrap tab dynamically with data sent from the server via Ajax. Inside every tab there is certain elements from another json source. Lets say:

Model A:
  id
  name

Model B:
 id
 name
 fk_a

My observable arrays takes all the objects from A and all the objects from B and what I'm trying to achieve is to filter the elements of B from the current element at the Model A foreach:

<div class="tab-content" data-bind="foreach: arrayA">
    <div class="tab-pane" data-bind="attr: { id: 'div_grupo_' + $data.id }">
         <!-- A foreach here of modelB filtered by modelA value -->
    </div>
</div>

So far, I have find someways to filter an observable array but I can't find the way to pass the parameter to the function who filters the array. I could set an

Here the ViewModel

function Grupo(id, nombre){
            var self = this;
            self.id = id;
            self.nombre = nombre;
        };

        function Subgrupo(id, nombre, grupo){
            var self = this;
            self.id = id;
            self.nombre = nombre;
            self.grupo = grupo
        }


        function MainConsultaViewModel() {
            var self = this;
            self.grupos = ko.observableArray();
            self.subgrupos = ko.observableArray();

            self.filtroSubgrupos = ko.observable();

            this.subgruposPorGrupo = ko.computed(function() {
                var filtro = this.filtroSubgrupos();
                return ko.utils.arrayFilter(this.subgrupos(), function(filtro) {
                    return subgrupo.grupo == filtro;
                });
            }, this);

            var cambiaFiltro = function(valor){
                self.filtroSubgrupos(valor);
            }

            $.getJSON('some/url', function(data){
                $.each(data.objects, function (i, val) {
                    self.grupos.push(new Grupo(val.id, val.nombre));
                });
                console.log(self.grupos());
            });

            $.getJSON('some/other/url'+self.tipo_consulta, function(data){
                $.each(data.objects, function (i, val) {
                    self.subgrupos.push(new Subgrupo(val.id, val.nombre));
                });
            });

        };

        ko.applyBindings(new MainConsultaViewModel());

What I'm missing here? Is it possible to achieve this?

Cheers

Was it helpful?

Solution

ko.utils.arrayFilter Solution :

Example keeping with the ko.util.arrayFilter usage.

  1. If a selection event will be affecting the group by which to filter, you could use an observable + computed combination where the computed performs the filtering.
  2. If the data is static and simply needs filtering upon render, you would pass the "current" group to a function that performs the filtering.

    Both scenarios detailed in the provided example link.

Alternative Solution: Alias (Note 3) your data and use an if binding to perform the filtering.

Example:

<ul data-bind="foreach: {data: A, as: 'dataA'}">
  <li><span data-bind="text: dataA.id "></span></li>
  <ul data-bind="foreach: {data: $root.B, as: 'dataB'}">
    <div data-bind="if: $root.equals(dataA, dataB)">
        <li> <span data-bind="text: dataB.other "></span></li>
    </div>
  </ul>
</ul>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top