-
2 Jan 2013 11:38 PM #21
@praveenyk
I just set up a little sample-project with some basic code to create a MVC-App which shows some static data that is received from Ext-Direct with PHP (see the attached ZIP-File for the full source-code):
App.js:
Viewport.js (View):PHP Code:Ext.define('TD.Application', {
extend: 'Ext.app.Application',
name: 'TD',
appFolder: 'app',
controllers: [ 'Users' ],
autoCreateViewport: false,
launch: function() {
Ext.create('TD.view.Viewport');
}
});
Ext.onReady(function() {
Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
Ext.create('TD.Application');
});
User.js (Controller):PHP Code:Ext.define('TD.view.Viewport', {
extend: 'Ext.container.Viewport',
layout: 'fit',
items: {
xtype: 'userlist'
}
});
User.js (View):PHP Code:Ext.define('TD.controller.Users', {
extend: 'Ext.app.Controller',
views: [ 'User' ],
stores: [ 'Users' ],
models: ['User']
});
User.js (Model):PHP Code:Ext.define('TD.view.User' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
title: 'All Users',
store: 'Users',
columns: [
{ header: 'Name', dataIndex: 'name', flex: 1 },
{ header: 'Email', dataIndex: 'email', flex: 1 }
]
});
Users.js (Store):PHP Code:Ext.define('TD.model.User', {
extend: 'Ext.data.Model',
fields: [ 'name', 'email' ]
});
Users.php:PHP Code:Ext.define('TD.store.Users', {
extend: 'Ext.data.Store',
model: 'TD.model.User',
proxy: {
type: 'direct',
reader: {
type: 'json',
root: 'result'
}
},
constructor : function(config) {
// The direct-handler-function needs to be applied in the constructor because if we'd do it in the config
// there would be errors after deployment of the app (see http://www.sencha.com/forum/showthread.php?196544-MVC-direct-proxy-and-load-order)
Ext.applyIf(this.proxy, {
directFn: Users.getAllUsers
});
this.callParent([config]);
},
autoLoad: true
});
PHP Code:<?php
class Users {
public function getAllUsers() {
// return some static data...
$users = Array(
Array(
"name" => "Ed",
"email" => "ed@sencha.com"
),
Array(
"name" => "Tommy",
"email" => "tommy@sencha.com"
)
);
return $users;
}
}
For further explanations about basic MVC and Ext-Direct stuff, see the guides from ExtJS documentation:
http://docs.sencha.com/ext-js/4-1/#!...n_architecture
http://docs.sencha.com/ext-js/4-1/#!...irect_grid_pt1
-
3 Jan 2013 2:51 PM #22
I had a similar problem. Solved it by defining direct functions in constructor!
Code:Ext.define('App.model.Type', { extend: 'Ext.data.Model', idProperty: 'typeId', fields: [ {name: 'typeId', type: 'int'}, {name: 'type', type: 'string'} ], proxy: { type: 'direct' }, constructor: function() { Ext.apply(this.proxy, { api: { create : App.api.Type.create, read : App.api.Type.read, update : App.api.Type.update, destroy : App.api.Type.destroy } }); this.callParent(arguments); } });
-
3 Jan 2013 5:11 PM #23
Another solution is to define a custom direct that proxy, that stores function references as strings, and tries to parse api functions on request. I wonder which method is better/faster?
This way you can define model proxy with string referencesCode:Ext.define('App.data.proxy.Direct', { extend: 'Ext.data.proxy.Direct', alias: 'proxy.customdirect', constructor: function(config){ var me = this; me.callParent(arguments); me.directFn = config.directFn; me.api = config.api; }, getApiFn: function(request) { var me = this; if (me.api.hasOwnProperty(request.action)) { return Ext.direct.Manager.parseMethod(me.api[request.action]); } else if (me.directFn) { return me.directFn; } else { return null; } }, doRequest: function(operation, callback, scope) { var me = this, writer = me.getWriter(), request = me.buildRequest(operation, callback, scope), fn = me.getApiFn(request), params = request.params, args = [], method; //<debug> if (!fn) { Ext.Error.raise('No direct function specified for this proxy'); } //</debug> if (operation.allowWrite()) { request = writer.write(request); } if (operation.action == 'read') { // We need to pass params method = fn.directCfg.method; args = method.getArgs(params, me.paramOrder, me.paramsAsHash); } else { args.push(request.jsonData); } Ext.apply(request, { args: args, directFn: fn }); args.push(me.createRequestCallback(request, operation, callback, scope), me); fn.apply(window, args); } });
Code:Ext.define('App.model.Type', { extend: 'Ext.data.Model', requires: [ 'App.data.proxy.Direct' ], idProperty: 'typeId', fields: [ {name: 'typeId', type: 'int'}, {name: 'type', type: 'string'} ], proxy: { type: 'customdirect', api: { create : 'App.api.Type.create', read : 'App.api.Type.read', update : 'App.api.Type.update', destroy : 'App.api.Type.destroy' }, reader: { type: 'json', root: 'data', idProperty: 'typeId', successProperty: 'success', messageProperty: 'message' }, writer: { type: 'json' } } });
-
8 Jan 2013 10:28 AM #24
In 4.2, this problem is solved: Direct proxy API functions are resolved at first call attempt instead of construction time.
Regards,
Alex.
-
20 Jan 2013 9:26 AM #25
Thanks! Finally I have Ext Direct wired up.
I can't believe how much time I have wasted attempting to get Ext Direct to work. I really don't understand Sencha's position on this, should we not be using Ext.application({}) as recommended...? Since there doesn't appear to be a way (out of the box) to get Ext Direct to work without extending the framework as suggested by HriBB.
I was simply going around in circles either resulting in the method being unresolved or directCfg being unresolved. Crazy!
It makes more sense to define the remoting methods as Strings anyhow, especially when using an IDE that attempts to resolve function / object instances in the project.
-
28 Feb 2013 9:20 PM #26
And hopefully for Touch 2.2 as well?
A security feature wish of mine is that I use use plain AJAX or whatever to do login authentication and then only permit loading the Direct RPC API once authenticated. This obviously requires delayed binding to stores which hopefully this recent fix will now support (right?).
-
3 Mar 2013 5:31 PM #27
FYI ... I found that this solution triggered another (rather worrying) exception in my ST 2.1.1 app ...Code:Just init your Ext.Direct API in Application's constructor and it'll be fine.
In Ext.setup() .... Ext.event was undefined when the factoryConfig callback fired.
This is interesting because it suggests that there might be a race condition as just a few lines before is code that should have defined the value if it was performed before the callback fired:Code:Ext.onDocumentReady(function() { Ext.factoryConfig(config, function(data) { Ext.event.Dispatcher.getInstance().setPublishers(data.eventPublishers);
Code:Ext.require(['Ext.event.Dispatcher']);
-
5 Mar 2013 3:51 PM #28
That advice you quoted was aimed at Ext JS apps; Sencha Touch has a wee bit different Ext.Direct implementation and I'm not 100% sure it works the same way. So please take it with a grain of salt.
Regards,
Alex.


Reply With Quote