How to use Ext.create properly - extjs

Can't find any relevant information in the sencha documention about this question :
Is it possible to call Ext.create(...) with a parameter which does not depend on the application's name?
So that if I change the app's name I don't have to rewrite that line of code?
Normally I would use Ext.create(AppName.model.MYMODEL) but that's too tied to the app's name for me.
Still need help :)

Create using class alias
When using Ext.define to define your class, you can provide an alias property. You've probably seen this on UI components which use aliases like widget.panel. Those aliases can be used with Ext.create.
Ext.define('MyApp.SomeClass', {
alias: 'app.someclass', // Independent of class name
/* ... */
});
Ext.create('app.someclass', {
/* ... */
});
You can set the alias on a class after it has been created by using Ext.ClassManager.setAlias.
Helper function using application name
If you don't have the option to set an alias, you could create a function that wraps Ext.create which supplies your base namespace automatically.
The problem here is that Ext.application doesn't return the application object. I'm not sure how Sencha Architect generates the application code but you may need additional overrides to allow you to retrieve the application object.
function appCreate(className, config) {
var appName = someMethodThatGetsTheApplicationName();
return Ext.create(appName + '.' + className, config);
};
// Example usage: Creates object of MyApp.model.MyModel
var myObj = appCreate('model.MyModel', { /* ... */ });
How to get the application name at runtime
By default, Ext JS does not retain a reference to the application object when using Ext.application, so we need an override to do it. I'm using Ext.currentApp as the property to store this object, but you can change it to whatever you'd like.
Ext.application = function (config) {
Ext.require('Ext.app.Application');
Ext.onReady(function () {
Ext.currentApp = new Ext.app.Application(config);
});
};
Now that you have this, you can access the application name by simply using Ext.currentApp.name. Or, if you'd feel more comfortable using a getter you can use the following.
Ext.app.Application.addMembers({
getName: function () {
return this.name;
}
});
// Example usage:
function someMethodThatGetsTheApplicationName() {
if (!Ext.currentApp) {
Ext.Error.raise('Current app does not exist.');
}
return Ext.currentApp.getName();
}

You can use any class name in Ext.create there is no naming convention imposed there as long as the class was already defined. If you want Ext.create to load the correct file using Ext.loader you will need to configure the loader to conform with the naming convention you need.

The way to do it :
You need a controller that will in it's INIT function (before UI Loading/Initiating) do the following
APPNAME = this.getApplication().getName();
Where APPNAME is a global variable.
Then when you Ext.create something you will be able to write the following
Ext.create(APPNAME +'model.MyModel');
That way you can change you app name without having to check everywhere in your code to change every single Ext.create to the new app's name.
It also give you the ability if you are to use this.getApplication().setName() to have infinite cache storage has you get 5/10mb per AppName.

Related

short names for extjs classes and namespaces

i have something like
Ext.define('HS.controller.Utility', {
statics : {
state : 'Oklahoma'
}
});
Now i want to access it from my controllers, but in every method of controller, i have to write HS.controller.Utility.state to access it. currently i'm doing this : var ut = HS.controller.Utility and then accessing state as ut.state, but again, i've to declare this variable in every function. Is there a way to set it to a short name once in my controller and then access from all functions?
There are several ways you could do it, the best of which:
// Becomes a global variable
var X = Ext.define('My.long.class.Name');
// Set a reference on your main NS at launch time
launch: function() {
MyApp.X = My.long.class.Name;
}
Even easier than the current answer is to just declare an alternateClassName with no namespace. Only one line of code, no initialization or race conditions, built into ExtJs.
Ext.define('HS.controller.Utility', {
//
// Non-namespaced alternate class name will create
// 'globally defined' Utility object.
//
alternateClassName: 'Utility',
statics : {
state : 'Oklahoma'
}
});
});

Overwrite properties in angular forEach

I imagine this is an easy thing to do, but I wasnt able to find the information I was looking for through google. I have popupProperties which is just default stuff. I then call to the service which returns specific overrides depending on the popup. How can I iterate through all of the service's overrides and apply them to the popupProperties?
var popupProperties = getDefaultPopupProperties();
var popupOverrides= popupService.getPopupOverrides(currPopupId);
angular.forEach(popupOverrides, function(popupProperty, propertyName){
//replace defaults with popupData's properties
});
You should have a look at the solution of Josh David Miller which uses the extend method of angular (documentation).
var defaults = {name:'John',age:17,weight:55};
var overrides = {name:'Jack',age:28,color:'brown'};
var props = angular.extend(defaults, overrides);
// result
props: {
name:'Jack',
age:28,
weight:55,
color:'brown'
}
The values are copied in the defaults variable. There is no need of using the return value (var props =).
I presume you mean both functions are returning objects with a number of properties (as opposed to an array).
If so, the following should work - just JavaScript, nothing AngularJS specific:
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
See this question for more details How can I merge properties of two JavaScript objects dynamically?

how to set default prefix in controller -> skip defining prefix in links

I have the following idea: I'd like to be able to define the default prefix in any given controller. So let's say the default prefix for the CitiesController implements all actions with the "admin" prefix ("admin_index", "admin_add", etc.), but the ProvincesController implements all actions with the
"superadmin" prefix ("superadmin_index", "superadmin_add", etc.)
The problem with this is, every time I want to link to any "city stuff", I have to specify "admin" => "true". Any time I want to link to any "province stuff", I have to specify
"superadmin" => "true".
That's already quite a bit of work initially, but if I decided I wanted to change the prefix from "admin" to "superadmin" for cities, it would be even more work.
So I was wondering if there's to somehow do something along the lines of:
class CitiesController extends AppController {
var $defaultPrefix = "admin"
}
And then in the HTML helper link function, do something like:
class LinkHelper extends AppHelper {
public $helpers = array('Html');
function myDynamicPrefixLink($title, $options) {
// check whether prefix was set (custom function that checks all known prefixes)
if (! isPrefixSet($options)) {
// no clue how to get the controller here
$controller = functionToGetControllerByName($options['controller']);
// check whether controller has a defined default prefix
$prefix = $controller->defaultPrefix;
if ($prefix) {
// set the given prefix to true
$options[$prefix] = true;
}
// use HTML helper to get link
return $this->Html->link($title, $options);
}
}
I just have no clue how to get from the helper to the controller of the given name dynamically.
Another option would be to store the default prefix somewhere else, but for now I feel that the best place for this would be in any given controller itself.
Another idea would be to even have that look up function dependent on both, the controller and the action, and not just the controller.
You should be able to use the Router::connect to supply defaults (see code and documentation on Github: link) to specify default prefixes for certain controllers and even actions.
However, if you want more flexibility than the current Router provides, you can extend your use of the Router::connect by specifying an alternate Route class to use:
Router::connect(
'/path/to/route',
array('prefix' => 'superadmin'),
array('routeClass' => 'MyCustomRouter')
);
Examples of this can be seen in the CakePHP documentation.

How to use Ext.define in ExtJS 4?

I'm new to ExtJS 4 and need some help understanding how the Ext.define works, please.
In fact what I want to do is something similar to the portlets in the portal example, in my application I will need so many objects to add in my different tabs, so in order to organize my code and not have just one very big script, I want to define each component I need in a separate file and then call it in the main script when I need it (I will mainly use the examples so this is why I want to know how Ext.define works so I can adapt those examples and make them work the way I want).
I hope I was clear.
And thank you in advance for your help.
Ext.define ( String className, Object data, Function createdFn ) : Ext.Base
Ext.define is used to define a class. Example:
// creates My.computer.NoteBook Class
Ext.define('My.computer.NoteBook', {
extend:'Ext.panel.Panel',
config: {
hardware:'Dell',
os:'Linux',
price:500
},
constructor:function(config) {
this.initConfig(config);
return this;
}
});
// creates instance of My.computer.NoteBook Class
var myComputer = Ext.create('My.computer.NoteBook', {
hardware:'MacBook Pro',
os:'Mac OS X',
price:1800
});
so, with Ext.define you make a mold, witch you can use later in many cases. You can define width, height, id, css, so later you just call that mold/class. In your case you can define a class for every tab, and then when you make a function to open/create that tab you can say:
if(existingTab){
mainPanel.setActiveTab(existingTab);
}else{
mainPanel.add(Ext.create('My.computer.NoteBook', {id:tabId})).show();
}
...
You can put every Class in your separate .js file, later, on production you will make a class.js with all classes in one minified .js file!
You can define a class and then say:
items: Ext.create("My.computer.NoteBook",{
...
})
Ext JS 4 has a new way to extend... it's call Ext.define and it incorporates Ext.extend, Ext.reg and Ext.ns that we had to do in Ext JS 3 and before into one method call...
Ext.define('com.sencha.MyPanel', {
extend : 'Ext.panel.Panel',
alias : 'widget.mypanel',
...
...
});
Ext.define takes two params, first is the full class name (will act as Ext.ns to create the path and will create the Object) and the config. In the config you specify what class you are extending using the extend config. You set up an XType using the alias config. The alias config is a little different as it has two parts... first part is the type (widget in this case) and then the XType (mypanel).

Cakephp Localization, Cannot Change language when DEFAULT_LANGUAGE is set

I am confused :)
I'm using the p18n component in cakephp found here:
http://www.palivoda.eu/2008/04/i18n-in-cakephp-12-database-content-translation-part-2/
This component requires me to set in core.php the following constant:
define("DEFAULT_LANGUAGE", 'eng')
However when this is set I cannot change the language using:
Configure::write('Config.language', 'eng');
At the moment, into my knowledge, the only way to change the locale of my static content is the use of the Configure::write. But for the dynamic content to change through the use of the p28n component I must have the DEFINE_LANGUAGE constant set to a value.
This is all very confusing. Any help will be much appreciated.
I'm not familiar with particular component, but I've done this "manually" by setting the same constant in my app/config/bootstrap.php file and then setting the "actual" language to be used in my AppController (copied from the core code to app/app_controller.php). The appropriate snippets of that controller look like this:
uses ( 'L10n' );
class AppController extends Controller {
public function beforeFilter() {
$this->_setLanguage();
/**
* Set the default "domain" for translations. The domain is the
* same as the po file name in a given locale directory. e.g.
* __d ( 'homepage', 'message_id' ) would look for the
* message_id key in homepage.po. Using the __() convenience
* function will always look in default.po.
*/
$this->set ( 'domain', 'default' );
}
private function _setLanguage() {
$this->L10n = new L10n();
# Auto-detect the request language settings
$this->L10n->get();
}
}
Pretty vanilla stuff, but it works great. And breaking out the _setLanguage() method allows for the use of different methodologies to determine locale (e.g subdomain like fr.mydomain.com).

Resources