Create component table with Knockout

2

I have the following code using Ajax to fetch the data in a Restful and loading the fields in a UserList array with knockout:

  $.ajax({
    type: "GET",
    url: "http://192.168.15.4/api/usuarios",
    contentType: "application/javascript",
    dataType: "json",
    beforeSend: function () {
        $('#imageLoad').show();
        $('#imageError').hide();
    },
    success: function (result) {
        var observableData = ko.mapping.fromJS(result);
        var array = observableData();
        self.ListaUsuarios(array);

        // Method to filter the assets table based on user input.  Computed observable is throttled to ensure it doesn't kick in too quickly.
        self.filteredAssets = ko.computed(function () {
            debugger;
            var filter = self.filter();
            if (!filter) {
                return self.ListaUsuarios();
            } else {
                return ko.utils.arrayFilter(self.ListaUsuarios(), function (item) {
                    return item.login().indexOf(filter) > -1;
                });
            }
        }).extend({
            throttle: 500
        });
        self.selectedAsset = ko.observable();
        self.selectAsset = function (item) {
            self.selectedAsset(item);
        };
    })

I've loaded a table into the html page using the UserList array previously loaded with knockout mapping , specifying the fields I want.

  <table class="table table-bordered table-hover">
        <thead>
            <tr>
                <th align=center width=60 style="display: none">Código</th>
                <th>Nome/Razão social</th>
                <th>Login</th>
                <th>CPF/CNPJ</th>
                <th>Email</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: {data: ListaUsuarios()}">
            <tr>
                <td style="display: none" data-bind="text: id"></td>
                <td data-bind="text: pessoa.razao_social"></td>
                <td data-bind="text: login"></td>
                <td data-bind="text: pessoa.cpf_cnpj"></td>
                <td data-bind="text: email"></td>
            </tr>
        </tbody>
    </table>

This code works perfectly. But I wanted to create a template with this table so I did not have to repeat the code for every different table I had, for example the table would be:

 <tbody data-bind="foreach: {data: ListaUsuarios()}">
      <tr>
         //aqui a table seria criada dinamicamente atraves do componente com template criado no knockout.
      </tr>
 </tbody>

The rest would be in charge of the component that loads the template, I tried to do this using some examples such as  : link but without success

the json received is:

[{"pessoa":{"id":1,"tipo":"J","razao_social":"INTELIDER","nome_fantasia":"INTELIDER LTDA","cpf_cnpj":"10999558000186","rg_insc_estadual":"132456789"},"id":1,"login":"gleyson","senha":"123456","email":"[email protected]","ativo":"S"},{"pessoa":{"id":11,"tipo":"J","razao_social":"I9MAKER LTDA","nome_fantasia":"INTELIDER LTDA","cpf_cnpj":"00000000000000","rg_insc_estadual":"123456"},"id":11,"login":"sistemas","senha":"123456","email":"[email protected]","ativo":"S"}]"
    
asked by anonymous 04.08.2017 / 04:14

1 answer

3

For some reason knockout components do not work inside a table without using the "virtual elements" feature. So, I did this jsFiddle to exemplify what your use case would look like. I used the JSON data you provided in the question.

I hope I have helped!

Edit: Added code in response

ko.components.register('user-component', {
    viewModel: function(params) {
    	  debugger;
        this.id = params.id;
        this.login = params.login;
        this.pessoa = params.pessoa;
        this.email = params.email;
    },
    template:
        '<td data-bind="text: id"></td>' +
        '<td data-bind="text: pessoa.razao_social"></td>' +
        '<td data-bind="text: login"></td>' +
        '<td data-bind="text: pessoa.cpf_cnpj"></td>' +
        '<td data-bind="text: email"></td>'
});

function Product(name, rating) {
    this.name = name;
    this.userRating = ko.observable(rating || null);
};

function MyViewModel() {
    this.products = ko.observableArray([
    	{
      	"pessoa":{
        	"id":1,
          "tipo":"J",
          "razao_social":
          "INTELIDER",
          "nome_fantasia":"INTELIDER LTDA",          
          "cpf_cnpj":"10999558000186",
          "rg_insc_estadual":"132456789"
        },
        "id":1,
        "login":"gleyson",
        "senha":"123456",
        "email":"[email protected]",
        "ativo":"S"
      },
      {
        "pessoa":{
        	"id":11,
          "tipo":"J",
          "razao_social":"I9MAKER LTDA",
          "nome_fantasia":"INTELIDER LTDA",
          "cpf_cnpj":"00000000000000",
          "rg_insc_estadual":"123456"
        },
        "id":11,
        "login":"sistemas",
        "senha":"123456",
        "email":"[email protected]",
        "ativo":"S"
        }
    ]);
}
 
ko.applyBindings(new MyViewModel());
table td, table th {
  border: 1px solid #CCC;
  padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script><table><thead><tr><th>ID</th><th>RAZÃOSOCIAL</th><th>LOGIN</th><th>CPF/CNPJ</th><th>EMAIL</th></tr></thead><tbodydata-bind="foreach: products">
  <tr>
    <!-- ko component: { name:"user-component", params: $data } --><!-- /ko -->
  </tr>
</tbody>
</table>
    
14.08.2017 / 15:00