[OPEN] [#1859] Bind event with component column

  1. #1

    [OPEN] [#1859] Bind event with component column

    Hello

    I have a problem with component column, narrowed town to the example below

    could you please explain me why bind event is called two times for first item in the grid?
    any next item added, bind event is fired just single time

    Store behind - there is very very complex grid behind this example, and calling binding two times, causes "flickering" when rendering

    
    <%@ Page Language="C#" %>
    
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>Two bind events</title>
        
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <h1>ComponentColumn as Editor</h1>
            <ext:Viewport runat="server">
                <Items>
                    <ext:Panel runat="server"  Controller="MyController">
                    </ext:Panel>
                </Items>
            </ext:Viewport>
        </form>
    </body>
    
    <script>
        Ext.define('MyController',
            (function () {
                var publicInterface = {
                    extend: 'Ext.app.ViewController',
                    alias: 'controller.MyController',
                    init: function (view) {
                        this.callParent(arguments);
    
                        var cnt = new UserPropertyEdit();
                        view.add(cnt);
    
                        var grid = cnt.down('grid');
                        grid.columns[0].on('bind', bindOnColumn, this);
                    }
                };
    
                function bindOnColumn() {
                    console.info('bind has been called'); // why this is called two times for first item?
                }
    
                return publicInterface;
            })());
    
    
    
        function addAttribute() {
            var rootPanelTemp = Ext.getCmp('rootPanelTemp');
            var grid = rootPanelTemp.down('grid');
            grid.store.add({
                Name:'data'
            });
        }
    
        Ext.define('UserPropertyEdit', {
            
            id:'rootPanelTemp',
            "extend": "Ext.Panel",
            items: [{
                store: {
                    model: Ext.ClassManager.isCreated(Ext.id()) ? Ext.id() : Ext.define(Ext.id(), {
                        extend: "Ext.data.Model",
                        fields: [ {
                            name: "Name",
                            type: "string"
                        }]
                    }),
                    autoLoad: true,
                    proxy: {
                        type: 'memory'
                    }
                },
                frame: true,
                margin: "5",
                reference: "dgvGrid",
                xtype: "gridpanel",
                buttons: [{
                    reference: "btnAdd",
                    iconCls: "#Add",
                    text: "Add Extended Attribute",
                    handler:addAttribute
                }],
                columns: {
                    items: [{
                        xtype: "componentcolumn",
                        flex: 1,
                        dataIndex: "Name",
                        text: "First Column",
                        component: function () {
                            return [{
                                xtype: "textfield",
                                validateOnFocusLeave: true
                            }];
                        },
                        editor: true
                    }]
                }
            }],
            layout: "fit"
        });
    </script>
    </html>
  2. #2
    Hello @lbrohan!

    I can't really tell why this event is triggered in the first place; I don't see documentation on this event (bind) in Ext.grid.colum.Column supported event list.

    So it seems your code relies on unsupported event and you should avoid using it; that is, it may work now, but there's no guarantee its behavior is going to change in the future if there's no designed handler for it.

    I believe you should look up from the link above for supported events that fulfill the task you need to accomplish. Then if the chosen event also fires twice for the same record, we can investigate its reasons.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Oh wait, I seem to have jumped too quick to conclusions; you are talking about the component column, which does have the bind event!..

    Checking up your example to get down to the reason why it fires twice and a possible hint on how to avoid this. We'll get back to you soon!
    Fabrício Murta
    Developer & Support Expert
  4. #4
    Okay, I have checked your test case; getting parse errors. Can you review it?

    Notwithstanding, I tried a test case based on Grid Panel > Component Column > Overview and it is not firing the event twice for any record in the grid; if I have 5 rows, the event fires 5 times; and I made it print the element's unique ID (Index in the related example), and it is not popping the same ID twice at any point.

    Looking forward to your follow-up!
    Fabrício Murta
    Developer & Support Expert
  5. #5
    Hello

    I'm sorry you got the parse error - I tried on two vistual studio versions on standalone projects and it works fine for me.
    Can I please ask what error says?

    I createt my sample from the sample you pointed me to. Till the component column is created in ascx/aspx it works fine - bind event is called just once, but once it is added dynamically, first time it is called twice. Based on my ivestigation its is caused by something related to "refresh" event of the grid view to be called 10 miliseconds defered... but it quite above my knowledge of extjs internals

    Thanks for help
    Louise
  6. #6
    The Controller setting needs to reference a System.Web.Mvc.ControllerBase derivate at line 18, where you have <ext:Panel runat="server" Controller="MyController">.

    Okay, it seems you are using the non-mvc-capable version of Ext.NET DLL (NuGet package), so this setting is not included -- in turn it just passes the config as controller: 'Mycontroller' to client-side.

    To get equivalent code using MVC Ext.NET version I will just change it to:

    <ext:Panel runat="server">
        <CustomConfig>
            <ext:ConfigItem Name="controller" Value="MyController" />
        </CustomConfig>
    </ext:Panel>
    Will follow up in a moment...
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Hello

    I'm little confused why you are mentioning Mvc in previous reply
    I'm nto using Ext.Net MVC ( otherwise I would be in bad forum no?)

    I'm adding just controller attribute and on my form it just render "controller" to config options like below
    Controler itself is defined in javascript - ie. on the bottom of my sample


     <script type="text/javascript">
        //<![CDATA[
            Ext.net.ResourceMgr.init({id:"ctl03",aspForm:"ctl01",appName:"ALA2WEB",locale:"en-US"});Ext.onReady(function(){Ext.create("Ext.net.Viewport",{renderTo:Ext.get("ctl01"),items:[{"controller":"MyController"}]});});
        //]]>
        </script>

    So why you are getting build error on Controller attribute?

    it's like I add this attribute

     <ext:Panel runat="server"  Controller="MyController" aaa="yyy">
                    </ext:Panel>
    (and in generated output I get "controller":"MyController","aaa":"yyy" )

    Regards
    Louise
  8. #8
    Hello again Louise!

    Quote Originally Posted by lbrohan
    could you please explain me why bind event is called two times for first item in the grid?
    any next item added, bind event is fired just single time
    The reason the event fires twice is that Ext JS original code implies a refresh in the view whenever the first record is added to the grid. This probably avoided some undisclosed issue and most likely when the ComponentColumn was implemented by us, this refresh was not implied; the component simply does not check, when adding the first record, if some other event triggered the grid view's refresh handler; thus it carries on with usual component addition, ultimately triggering the bind event, when it shouldn't.

    So, for this issue we have logged #1859 at GitHub, and will post an update to this thread as soon as we get that issue addressed.

    For the time being, if triggering the event twice is an issue, you can avoid this by checking if the bind event was triggered from the [var]itemAdded()[/bar] method when the view is just about to receive its first record.

    Unfortunately there's currently no reliable way to tell whether the event trigger is coming from this "double-trigger" scenario, and you probably want to skip the call if a refresh is scheduled for just 10ms in the future to trigger it again so I can't think on something that would nicely skip the double trigger without setting a global variable and making some assumptions.

    Changing your bindOnColumn() implementation to this should do:

    function bindOnColumn(column) {
        var singleTriggerSafe = true;
        if (column.getView().all.count == 1) {
            if (column.doubleItemAddSafe === undefined) {
                column.doubleItemAddSafe = null;
                singleTriggerSafe = false;
            } else {
                delete column.doubleItemAddSafe;
            }
        }
    
        if (singleTriggerSafe) {
            console.info('bind has been called'); // why this is called two times for first item?
        }
    }
    There may be (much) better solutions for this; the alternative above is not meant to be a permanent or absolute solution for the issue, but a suggestion on how to avoid the double call in a reasonably lightweight "guard" assuming the binding code is somewhat complex.

    In case it is a simple code, you shouldn't have issues with the double load. You could also check if the number of view entries doesn't change between calls if your code is better run first thing (and not delay the actual code for the last time it is called during a double-trigger event).

    Quote Originally Posted by lbrohan
    I'm little confused why you are mentioning Mvc in previous reply
    I'm nto using Ext.Net MVC ( otherwise I would be in bad forum no?)
    Don't worry about that; this just means anyone trying your test case with the Ext.NET MVC NuGet package (which also supports WebForms) won't accept your test case without the changes I mentioned. So I added the note to the thread for future reference only.

    Both Ext.NET WebForms (using ASPX engine) and Ext.NET MVC (using Razor syntax, MVC engine) are topics handled in this forums as long as we're dealing with Ext.NET 5.

    Again, don't worry, you posted on the right forum and the right question. Unfortunately it consists on a bug that most likely raised as Ext JS code evolved over time and some different internal behavior resulted in side effects to Ext.NET's exclusive client-side code (the ComponentColumn component is only available to Ext.NET users and not included with Ext JS framework if acquired straight from Sencha).

    I hope the solutions proposed above are reasonable for the time being; let us know otherwise, or if for one reason or another the suggested approaches can't be applied to your scenario to avoid the double-trigger; we'd be eager to help!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. [CLOSED] Dynamic header column component direct event Issue
    By legaldiscovery in forum 1.x Legacy Premium Help
    Replies: 4
    Last Post: Dec 21, 2015, 10:56 PM
  2. [OPEN] [#774] Component Column Editor add row not working properly
    By matrixwebtech in forum 2.x Legacy Premium Help
    Replies: 6
    Last Post: Jan 08, 2015, 12:05 PM
  3. Replies: 2
    Last Post: Aug 21, 2014, 8:55 AM
  4. [CLOSED] Component Column - Combobox change event issue in IE 8
    By PriceRightHTML5team in forum 2.x Legacy Premium Help
    Replies: 3
    Last Post: Apr 08, 2014, 3:49 PM
  5. Replies: 2
    Last Post: Jun 27, 2013, 10:18 PM

Posting Permissions