We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

ejGrid KnockoutJS integration incomplete?

See: http://jsplayground.syncfusion.com/w3vpj0dnThe idea is that I would have an observable array of view models with observable properties that would be manipulated (e.g. edit, display) within the grid. However, what I believe I am observing is that the grid supports the collection level (observable array data source), but not the detail (observable properties on row level view model.)Question: Is this observation correct? If so, that's a fairly significant feature gap.

11 Replies

TS Thavasianand Sankaranarayanan Syncfusion Team April 18, 2017 04:41 PM UTC

Hi Robert, 

Thanks for contacting Syncfusion support. 

We have analyzed your query and we are able to reproduce the reported issue from our end.  

Essential JavaScript Grid don’t have support to render the KO observable fields in the grid cells.   
  
But we can achieve your requirement in the queryCellInfo event of ejGrid control with the following workaround.  
  
  
<div class="content-container-fluid"> 
      <div class="row"> 
        <div class="cols-sample-area"> 
          <div id="Grid" data-bind="ejGrid: {  
                                          dataSource: dataSource, 
                                       ----------------- 
                                         columns: [ 
                            { field:'id', headerText: 'Identifier', isPrimaryKey: true, isIdentity: true, type: 'number' }, 
                            { field:'name', headerText:'Name' } 
                         ], 
                         queryCellInfo:queryCellInfo, 
                         ----------- 
 
          </div> 
        </div> 
        </div> 
    </div> 
        <script type="text/javascript"> 
          $(function () { 
            var models = []; 
            for (var i = 0; i < 10; i++) { 
              models.push({ id: ko.observable(i), name: ko.observable("Name " + i)}); 
            } 
             
            window.employeeView = { 
              dataSource: ko.observableArray(models), 
               queryCellInfo: ko.observable(function (args){ 
                    var val = args.data[args.column['field']]; 
                    if(ko.isObservable(val)) 
                      args.cell.innerHTML =  val();    
                  }) 
            }; 
            ko.applyBindings(employeeView); 
          }); 
        </script>  
  
We have prepared a sample in JsPlayGround.  
  

Regards, 
Thavasianand S. 



RM Robert Mims April 20, 2017 04:47 PM UTC

Thank you, Thavasianand, for your quick response.That helps with display, certainly - the challenge then is editing the cell and underlying view model property.Any suggestions there?My thought, based upon your response, would be something like:1. Use querycellinfo to update the field value for display (not replacing the HTML to retain current edit behaviors)2. Use cellEdit to commit the value to the underlying observable.Probably some overhead there, it'd be much cleaner if the grid supported read/write from observables within the datasource.


TS Thavasianand Sankaranarayanan Syncfusion Team April 20, 2017 04:57 PM UTC

Hi Robert, 

Thanks for your update. 

We have analyzed your query and we confirm that in our Syncfusion ejGrid KnockoutJS control have limited observable property. It has the observable property for dataSource array not for the single cell value. In previous update we have provided workaround to show the values in grid column’s cell and editing is not feasible for the ejGrid KnockoutJS control. 

Regards, 
Thavasianand S. 



RM Robert Mims April 20, 2017 05:00 PM UTC

Quite unfortunate.

I'll see if I can create a wrapping adapter using the events to obtain the desired behavior before abandoning use of the Syncfusion grid control. 

Thank you.

Robert.


RM Robert Mims April 21, 2017 01:23 PM UTC

Though not entirely integrated for all features, I thought I'd share a small adapter that works well for edits when you encapsulate your observables within a navigation property.

Given:

$.ejObservableToProperty = function (vm, propertyCollectionName) {
    /// <summary>Adds the observable properties of an encapsulated object to the target with get/set access</summary>
    /// <param name="vm" type="Object">The target object to receive the properties</param>
    /// <param name="propertyCollectionName" type="Object">The source object with observable properties</param>
    var properties = vm[propertyCollectionName];
    $.each(properties, function (n, v) {
        if (ko.isObservable(v)) {
            Object.defineProperty(vm, n, { get: v, set: v });
        }
    });
};
And a view model that encapsulates the properties like:

EmployeeViewModel =  function() {
     var self = this;
     self.properties = {
          id: ko.observable();
          name: ko.observable();
     };

     self.create = function(id, name){
          self.properties.id(id);
          self.properties.name(name);
          $.ejObservableToProperty(self, "properties");      
          return self;
     };
};

You can create view models that will add set/get access to the observable that displays and updates the underlying view model observable. You have to encapsulate to avoid name collisions, but it's a start towards something that appears to work more flexibly with the Grid and Knockout in my testing (and mock in the playground.)

It'd still be wonderful if Syncfusion could provide the comprehensive solution for the Grid and Knockout (display and edit.) :)

Robert


RM Robert Mims April 21, 2017 05:45 PM UTC

The behavior above coupled with interception of the Add and Delete actions via the gridActionBegin event to manipulate/adapt the underlying observable array with strongly typed models worked for me. (Read: I now have a read/write KnockoutJS compatible ejGrid.)

In recap:

1. Use the observable to property encapsulation above (or some compatible proxy projection that wraps the access to the observable via Object.defineProperty so that the ejGrid can interact with the observable.)
2. Intercept Add and Delete grid actions, cancel them and perform the Add/Remove operations on your observableArray.

Very little code at all. :)

Robert


TS Thavasianand Sankaranarayanan Syncfusion Team April 25, 2017 04:42 PM UTC

Hi Robert, 

Thanks for your update. 

We have analyzed your solution and currently we don’t have the plan to implement this feature. So, please use your given solution for the reported problem. 

Regards, 
Thavasianand S. 



RM Robert Mims June 7, 2017 06:28 PM UTC

Related to the Grid's support for Knockout JS:

The grid appears only to have clean-up and observable binding support for the properties within the observables value:

        observables: ["dataSource", "selectedRowIndex", "pageSettings.currentPage", "selectedRowIndices"],

Unlike the diagram, for instance, that has many, many more:

observables: [
            "nodes",
            "connectors",
            "locale",
            "enableContextMenu",
            "backgroundColor",
            "backgroundImage",
            "enableAutoScroll",
            "showTooltip",
            "bridgeDirection",
            "tool",
            "pageSettings.pageHeight",
            "pageSettings.pageWidth",
            "pageSettings.multiplePage",
            "pageSettings.pageBorderWidth",
            "pageSettings.pageBackgroundColor",
            "pageSettings.pageBorderColor",
            "pageSettings.pageMargin",
            "pageSettings.showPageBreak",
            "pageSettings.pageOrientation",
            "pageSettings.scrollLimit",
            "snapSettings.enableSnapToObject",
            "snapSettings.snapAngle",
            "snapSettings.snapObjectDistance",
            "snapSettings.snapConstraints",
            "dataSourceSettings.id",
            "dataSourceSettings.parent",
            "dataSourceSettings.root",
            "dataSourceSettings.dataSource",
            "dataSourceSettings.tableName",
            "dataSourceSettings.query",
            "layout.type",
            "layout.orientation",
            "layout.horizontalSpacing",
            "layout.verticalSpacing",
            "layout.marginX",
            "layout.marginY",
            "layout.fixedNode",
            "selectedItems.offsetX",
            "selectedItems.offsetY",
            "selectedItems.width",
            "selectedItems.height",
            "selectedItems.rotateAngle",
            "scrollSettings.horizontalOffset",
            "scrollSettings.verticalOffset",
            "scrollSettings.zoomFactor",
            "tooltip.templateId",
            "tooltip.relativeMode",
            "tooltip.alignment.horizontal",
            "tooltip.alignment.vertical",
            "contextMenu.items",
            "contextMenu.showCustomMenuItemsOnly"
        ],

This is important because the destroy implementation will not capture these references, if, for instance, you bind the editSettings.allowAdding property to an observable or expression. That results in a memory/subscription leak that will cause unexpected behavior and even browser crashes.

Robert


TS Thavasianand Sankaranarayanan Syncfusion Team June 9, 2017 10:32 AM UTC

Hi Robert, 

We have analyzed your query and we suspect that you want more number of ejGrid properties need to made as observable/two-way binding. In default, Observable/two-way binding property value can be changed through both the customer and controller end. 

For an example, selectedRowIndex property will be updated when a row is selected in Grid by controller end and it would be updated by customer also. So, there is a two way communication like when grid changes this property it notifies in the customer application and if customer made changes, then it will received by controller end. 

For property allowEditing, we don't change this property from our source. So, here we only have one way communication i.e., application changes will be notified to us. For this purpose, particular property is not required to be Observerable. It handled through KO's bindingHandlers change event. 

If we misunderstood your query then please share the below details for better assistance. 

  1. Share the scenario that you expecting to enable observable property for editing.
  2. Share the details, If you facing any issues regarding your expectation.

Regards, 
Thavasianand S. 



RM Robert Mims June 9, 2017 10:56 AM UTC

Thavasianand,

It was more an informative post/observation for others seeking guidance in integrating KnockoutJS with the Grid.

I know that while I was reviewing the examples and documentation, it was not evident (without source inspection) which properties were also managed by internal proxies that indirectly affected how one might approach integration (which for the full feature set of the grid, is not evident.)

While there are open tickets to address memory leaks I have found, and multiple binding extensions and facades created to facilitate better integration, it is important that developers know the difference in which properties will be cleaned-up and which will not to prevent undesired side-affects.

Long explanation short, no action with regard to my post is required by Syncfusion. I was commenting for the next developer like me who is trying to understand what to look for when they encounter issues with integrating KnockoutJS and the Grid.

Thank you.

Robert


TS Thavasianand Sankaranarayanan Syncfusion Team June 12, 2017 12:52 PM UTC

Hi Robert, 

We analyzed your query  

Query 1: Documentations links. 

For more information on observable/two-way binding support. Refer the following help documentation. 



Query 2:  There are open tickets to address memory leaks I have found.  
 
Please follow that respective incidents for that respective queries. 

Regards, 
Thavasianand S. 


Loader.
Live Chat Icon For mobile
Up arrow icon