Knockout-Contrib / KoGrid

A Knockout DataGrid
https://knockout-contrib.github.io/KoGrid/
280 stars 131 forks source link

$userViewModel 's non-obvious behavior notice #210

Open IvanSokalskyi opened 11 years ago

IvanSokalskyi commented 11 years ago

$userViewModel is using bindingContext to save viewModel, which is filling by KnockoutJS' internal logic, but that context can be changed by KnockoutJS is you are using "with":

For example, here is the page with 2 grids that have the same gridOptions, but will contain totally different $userViewModel values (for the first case it will be "clientvm", but for the second it will be "clientvm.someProperty"):

First:
<div data-bind="koGrid: clientvm.gridOptions"></div>

Second:
<!-- ko with: someProperty -->
  <div data-bind="koGrid: clientvm.gridOptions"></div>
<!-- /ko -->

So if you are playing some magic with $userViewModel inside your logic for this grids, you need to be sure that the same functions/properties are available on both models for "clientvm" and "clientvm.someProperty". In my case kgEditable stoped work for the second case, because "clientvm.someProperty" did not have required functions that were part of "clientvm".

I see 2 ways:

grid.$userViewModel = bindingContext.$root;

in place of

grid.$userViewModel = bindingContext.$data;

So it will always point to root vm, but in this case root view model will be too fat for big sites.

<!-- ko with: clientvm.gridvm -->
  <div data-bind="koGrid: gridOptions"></div>
<!-- /ko -->

So grids logic can be separated from one place.

sanderd commented 11 years ago

I would even prefer the bindingContext itself to be stored, instead of $root. The reason for this being, that you would miss relevant context information such as $parent for hierarchical data otherwise.