row.data(new_data) redraws the table, even if .draw() is not called.

row.data(new_data) redraws the table, even if .draw() is not called.

lokimotolokimoto Posts: 6Questions: 2Answers: 0

Hi,

in the docs for row.data() it states that

Note that when used as a setter, this method sets the data to apply to the table, but does not update the table's internal caches of data until the draw() method is called.

This is exactly what I wish to achieve since I would like to collect changes and then update everything together for better performance. But setting new data, seems to trigger a drawing as demonstrated here: https://jsfiddle.net/5tsu07yf/16/ (a klick on Update).

Thank you!

Answers

  • kthorngrenkthorngren Posts: 21,309Questions: 26Answers: 4,947

    I updated you fiddle to show when the table is drawn:
    https://jsfiddle.net/8s3cv72h/

    You will see the draw event when the table is loaded but not when you click Update. Once you perform a search, page change or sort then the table will be drawn again.

    Kevin

  • lokimotolokimoto Posts: 6Questions: 2Answers: 0

    Hi,

    thank you!

    But what causes the Name field to be updated to contain the new value Foo Bar? And is it possible to suppress this and update it in one draw call?

  • lokimotolokimoto Posts: 6Questions: 2Answers: 0
    edited February 2019

    I figured, that the "render" function is triggered anyway as can be seen here: https://jsfiddle.net/sj3Lwqfo/1/ which I would like to prevent.

    I guess I should then collect the changed data somewhere else, like in a copy of .rows().data() and then update the whole table at once?

    Hmm, I think this does not work since for rows.data() it states

    This method cannot be used to modify data in the table, only to retrieve it. Use the row().data() method instead which can be used as a setter.

  • kthorngrenkthorngren Posts: 21,309Questions: 26Answers: 4,947

    The table.row(0).data(data); statement causes the HTML table to be updated. I don't believe there is a way to use table.row(0).data(data); without updating the table. Datatables maintains a data cache which is all of the data in the table. The data cache is separate from the data displayed in the table on the page.

    Is there a particular problem you are trying to solve?

    Kevin

  • kthorngrenkthorngren Posts: 21,309Questions: 26Answers: 4,947

    More specifically the render function is executed for the display type:
    https://jsfiddle.net/vmygtz4o/

    But it doesn't run for sort, filter, etc.

    What problem are you trying to solve?

    Kevin

  • lokimotolokimoto Posts: 6Questions: 2Answers: 0

    I am trying to increase the performance of an update on the data. The table is quite big and at the moment I update it like this:

    table.rows( {selected:true} ).every( function () {
        let row_data = this.data();
        // ... do some modifications on the data
        this.data(row_data);
    });
    

    But this is then super slow when a lot of rows are selected. When doing performance evaluations I figured, that Layout and Recalculate Style is the biggest issue. When I do not update with this.data(row_data); it runs quite fast.

  • kthorngrenkthorngren Posts: 21,309Questions: 26Answers: 4,947

    You could update the table using JQuery or some other method that doesn't use Datatable API's. The render function wouldn't run but the displayed data would be the raw data not the rendered data. Once the loop is done the you could use rows().invalidate() to update the table. Not sure this would help with the overall speed though.

    Another option might be to compile the updated data into an array, use rows().remove() to remove the selected rows, the rows.add() to add the updated data and use draw() only after adding the data. Again not sure this will help with overall speed.

    I'm not familiar with the internals of render so not sure what Layout and Recalculate Style are specifically doing.

    What are your render functions doing?

    Kevin

  • kthorngrenkthorngren Posts: 21,309Questions: 26Answers: 4,947

    Not sure what you are updating in the row but maybe updating specific cells would help using cell().data().

    Kevin

  • lokimotolokimoto Posts: 6Questions: 2Answers: 0

    My render function adds some <span /> elements depending on the row content and the action, that triggered the update. It looks mostly like this:

    render: function ( data, type, row, meta ) {
        let result = ``;
        const has_foo = row.foo.length > 0;
        // ...
        if (has_foo && !has_bar) {
            result += '<span class="badge">spam</span>'
        }
        // ...
        return result;
    }
    

    Since I update pretty much the entire row, I will give your first proposal a try. Thanks a lot!

This discussion has been closed.