Question

I try to use Ext.Direct with the ExtJS 4 MVC structure, and I'm not able to add the provider.

I get the error Uncaught TypeError: Cannot call method 'addProvider' of undefined while calling addProvider:

Ext.Direct.addProvider(Ext.app.REMOTING_API);

I tried both in launch of the application and in initof the controller.

Ext.define('Dir.Application', {
    require: [
        'Ext.direct.*',
        'Ext.data.*',
        'Ext.grid.*'
    ],
    launch: function(){
        Ext.Direct.addProvider(Ext.app.REMOTING_API);
    }
    ...
});

and

Ext.define('Dir.controller.Main', {
    init: function(){
        Ext.Direct.addProvider(Ext.app.REMOTING_API);
    }
    ...
});

both give the same error.

Where is the correct location to put addProvider into the code ?

Update: applying the recommendations of @rixo.

Ext.define('Dir.Application', {
    view:['Grid'],
    requires: [
        'Ext.direct.*',
        'Ext.data.*',
        'Ext.grid.*'
    ],
    launch: function(){
        Ext.Direct.addProvider(Ext.app.REMOTING_API);
    }
    ...
});

My view is defining a store and a proxy:

Ext.define('Dir.view.Grid', {
    extend: 'Ext.grid.Panel',
    store: {
        proxy: {
            type: 'direct',
            reader:{root: 'table'},
            api: {
                create: QueryDatabase.createRecord,
                read: QueryDatabase.getResults,
                update: QueryDatabase.updateRecords,
                destroy: QueryDatabase.destroyRecord
            }
        }
    ...
    }

Now the first error is OK, but I receiver an error complaining that QueryDatabase is not defined. It gets defined through the provider at Ext.Direct.addProvider(Ext.app.REMOTING_API); but it is not ready when the view is loaded through the views: [] declaration in the application definition.

Is there a way to get this working without nesting Ext.application inside Ext.onReady like in my solution?
No nesting would be better for the MVC way like explained here in the docs.

Was it helpful?

Solution

The require in your application definition won't do anything. It should be plural requires.

Also, you seem to have devised this in your own answer, but the name Ext.direct.Manager seems to be the favored by Sencha over Ext.Direct now.

Edit

According to the docs, you can set your direct functions using a string. Apparently, this is intended to solve exactly the kind of problems you've run into.

This should work and fix your issue:

api: {
    create: 'QueryDatabase.createRecord',
    read: 'QueryDatabase.getResults',
    update: 'QueryDatabase.updateRecords',
    destroy: 'QueryDatabase.destroyRecord'
}

OTHER TIPS

Probably you are missing the API definition before calling the provider, take a look to this definition from Sencha's examples page

Ext.ns("Ext.app"); Ext.app.REMOTING_API = {
"url": "php\/router.php",
"type": "remoting",
"actions": {
    "TestAction": [{
        "name": "doEcho",
        "len": 1
    }, {
        "name": "multiply",
        "len": 1
    }, {
        "name": "getTree",
        "len": 1
    }, {
        "name": "getGrid",
        "len": 1
    }, {
        "name": "showDetails",
        "params": ["firstName", "lastName", "age"]
    }], ...}]
} };

It should be included as a javascript file inside your webpage

 <script type="text/javascript" src="api.php"></script>

Something like this example.

Hope it helps.

Adding Direct providers is better done before the Application constructor runs:

Ext.define('Foo.Application', {
    extend: 'Ext.app.Application',

    requires: [
        'Ext.direct.Manager',
        'Ext.direct.RemotingProvider'
    ],

    name: 'Foo',

    constructor: function() {
        Ext.direct.Manager.addProvider(...);

        this.callParent(arguments);
    }
});

Ext.application('Foo.Application');

I found this solution:

Ext.require([
    'Ext.direct.RemotingProvider',
    'Ext.direct.Manager',
    'Ext.data.proxy.Direct'
]);
Ext.onReady(function(){
    Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
    Ext.application({
        name: 'Dir',
        extend: 'Dir.Application'
    });
});

It doesn't look really nice, because it uses the ExtJS 4 application instantiation inside a Ext.onReady.
At least it works. Maybe there is a better solution ?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top