Alexander
Alexander

Reputation: 59

ExtJS rendering after data loading

On the page, you need to draw one of the two icons. 'card.recurrentsupported' is of type 'Boolean'. At the input value == null. After loading the data, value == true, false or null. In the current implementation, the close icon is first drawn on the page, and after 0.5 seconds, after loading the data, if value == true, the icon is redrawn to check.

How can I wait for the data to load and then draw the icons?

renderer: function has additional parameters metadata, record, RowIndex, colIndex, store, view. Maybe I can use them to get a flag about loading data?

items: [                
            {
                ...
            },
            {
                fieldLabel: 'Support for recurrences',
                bind: '{card.recurrentSupported}',
                renderer: function (value) {
                    return value != null && value ? '<i class="fa fa-check text-green"></i>' : '<i class="fa fa-close text-red"></i>';
                }
            },
        ]

Card.js

Ext.define('App.view.card.Card', {
extend: 'Ext.form.Panel',
alias: 'widget.card',
requires: [
    'App.view.card.CardController'
],
controller: 'app.card',

viewModel: {
    security: {
        allowManageCard: 'card-update'
    },
    formulas: {
        merchantId: function (get) {
            var card = get('card');
            return card != null ? card.get('merchant') : null
        }
    }
},
modelValidation: true,

bind: {
    title: '{card.maskedPan}'
},

menuToken: 'cards',
tools: [
    {
        xtype: 'container',
        html: [
            '<ul class="breadcrumbs">',
            '<li><a href="#home"><i class="fa fa-home"></i></a></li>',
            '<li><a href="#cards">Cards</a></li>',
            '</ul>'
        ]
    }
],

defaults: {
    xtype: 'container',
    layout: 'form',
    defaultType: 'displayfield'
},

cls: 'adminkit-panel',

items: [
    {
        bind: {
            data: {
                blocked: '{card.blocked}',
                status: '{card.status}'
            }
        },
        data: {empty: true},
        tpl: [
            ...
        ],
        width: 70
    },
    {
        columnWidth: 0.5,
        items: [
            ...                
        ]
    },
    {
        columnWidth: 0.5,
        items: [
            ...
            {
                fieldLabel: 'Support for recurrences',
                bind: '{card.recurrentSupported}',
                renderer: function (value) {
                    return value != null && value ? '<i class="fa fa-check text-green"></i>' : '<i class="fa fa-close text-red"></i>';
                }
            },
        ]
    }
]

});

CardController.js

Ext.define('App.view.card.CardController', {
alias: 'controller.app.card',
extend: 'AdminKit.EntityViewController',

entityType: 'Card',

initViewModel: function() {
    var vm = this.getViewModel();
    vm.bind('{merchantId}', function (merchantId) {
        if (vm.get('merchantId') != null){
            Rpc.MerchantManager.resolve({id: merchantId}, function (err, res){
                vm.set('merchantName', res != null ? res.name : null)
            })
        }
    })
},

...
});

I solved the problem by replacing bind: '{card.recurrentSupported}' with bind: {value: {isrecurrent: '{card.recurrentsupported}'}}. This way we can track when the data was loaded. At the start of rendering, value = "", and after loading the data, value = {isRecurrent: true, false or unndefined}. Sometimes, an object is created, but the data does not have time to load, then value.isRecurrent == null.

{
                fieldLabel: 'Support for recurrences',
                bind: {value: {isRecurrent: '{card.recurrentSupported}'}},
                renderer: function (value) {
                    if (!Ext.isEmpty(value) && value.isRecurrent != null) {
                        return value.isRecurrent ? '<i class="fa fa-check text-green"></i>'
                            : '<i class="fa fa-close text-red"></i>';
                    } else if (!Ext.isEmpty(value) && value.isRecurrent === undefined) {
                        return '<i class="fa fa-close text-red"></i>';
                    } else {
                        return ''
                    }
                }
            }

Option, with the addition of a field that is exactly filled in

{
                fieldLabel: 'Support for recurrences',
                bind: {value:  {pan: '{card.maskedPan}', recurrentSupported: '{card.recurrentSupported}'}},
                renderer: function (value) {
                    if (value.pan == null) {
                        return '';
                    }
                    return value.recurrentSupported ? '<i class="fa fa-check text-green"></i>'
                        : '<i class="fa fa-close text-red"></i>';
                }
            },

Upvotes: 0

Views: 306

Answers (1)

Dinkheller
Dinkheller

Reputation: 5054

There are different approaches possible.

EVENT LISTENER

stores: {
    myStore: {
        url: 'getDataUrl',
        listeners: {
            load: function() {
                const view = Ext.create('newView')
            }
        }
    }
}

DATABINDING

xtype: 'myView' bind: {hidden: '{myStore.loading}'}

Upvotes: 1

Related Questions