extjs - dot notation to bracket {} notation? - extjs

not sure that that is a good title ...
I can get code behind a button to:
TabBar.activeTab.setTitle("New Tab");
but I need to do something like:
TabBar.activeTab.items = { title: "New Tab"
};
so I can eventually automate several tab properties in a loop:
TabBar.activeTab.items = { [key]: [value]
};
Am I correct in thinking config and items can only be used on construct()? Is there a way of doing the above? tia.

It depends on the implementation of the component and config property in question whether it can simply be set or requires a method call to be applied.
You are correct that in ExtJs many config properties are interpreted at construction time. Some are interpreted at render time. Once an Ext.Component is rendered almost all properties require an explicit method call to be applied correctly.
In general, I recommend to always use a method call to change a property after construction time if available in order to not break the inner workings of the component. If you look at the implementation of Ext.panel.Panel#setTitle you can see that there is a lot of stuff going on under the hood, e.g. event firing, etc.
ExtJs 4 configuration
Ext 4 introduced an explicit 'config' mechanism that might serve your purpose. However, my understanding is that most ExtJs components are not (yet?) using it.
Check out '2. Configuration' in the ExtJs Class System Guide
Create objects from xtype/config literals
If you want to add new components to a container (e.g. tabs to a tab panel) it would be rather easy to accomplish.
Use Ext.ComponentManager#create (see [docs][2]) to create an actual component object/instance from your config literal.
Ext.container.Container#add actually calls this method internally, so you can simply pass config objects to the add method.
If you want to remove or add tabs to a panel, there is now way around calling the proper methods.
applyConfig()
Of course you could always implement your own applyConfig method that supports changing certain component configuration properties at runtime by 'translating' the config into the proper method calls.

Related

Angular 2: Component input/output or updating a service property

Learning Angular 2 and trying to understand when I should use a component input/output and when I should better update a service property (possibly attached with an EventEmitter if updates are needed).
I have a list of, say, tasks, and each list items shows various info and options for this list item. This list works in the way that only one list item is active, and the active one is on the top of the list. One of those options for each list item is to activate it (if it is not already active), but other components could also possibly change which is the active item.
I have a parent task component, list component and a list-item component (and some other related components), and in addition I have a task-service.
The main taskcomponent could use listcomponent (and something-realted component, many of the components used needs to know and possibly change the activeItemId), like this:
<list [(active-item-id)]=“activeItemId”></list>
<something-related [(active-item-id)]=“activeItemId”></something-related>
The listcomponent could use list-item this way (active is a pipe and also a property on item):
<list-item *ngFor=“#item of items | active”
(item)=“item”
[(active-item-id)]=“activeItemId”>
</list-item>
But since I have a task-service that contains various task related, I could on the service use the already existing activeItemId-property (that has an eventemitter), and all the various task-components could just get info (and be updated) via this property, instead of “sending” the property back and forth via various components via inputs/outputs.
When would it be appropriate to just use a service for something like this and when would it be appropriate to use input/outputs for components instead?
Got a great answer via Angular Google Groups:
Without reading your full explanation, I'd say use binding if
possible, otherwise use a shared service.
Binding is not possible when
- the two components aren't direct parent/children
- the component is added by the router
- the component is added by DynamicComponentLoader
If you share the data between several components at once it might be
easier to not use binding even when one or some of them are direct
children.
Thank you, Günter!

CakePHP multiple controllers using same method

I have a method (the function in the controller, am I terming that correctly?) and view that I want to use in every controller on my site. Is there a way to make the method global across all controllers and the view .ctp file generic as well? I'd rather not have to copy-paste it everywhere.
This seems like something that should be obvious, so if I'm just searching for the wrong terms, let me know.
Thanks
Shared/Common Controller Code:
What you've described is a "Component":
Components are packages of logic that are shared between controllers.
If you find yourself wanting to copy and paste things between
controllers, you might consider wrapping some functionality in a
component.
See: http://book.cakephp.org/2.0/en/controllers/components.html
Shared/Common View Code:
As far as the View is concerned, there are a few options. If you want the entire view, you can just specify which view to render: $this->render('TestView/index');
Or, if you want a small chunk of code, you can try an Element.
All together:
If you find yourself creating a lot of the different "parts" (View, Controller/Component, Model/Behavior)...etc, all for the same general purposes (ie cropping a photo), you could think about creating a Plugin.
Side note:
Side note: Usually, I've heard the functions in Controllers referred to as "actions", and the functions in Models called "methods". They're all really methods (a function within a class/object), but - that's how they're commonly referred to.
You can put the method in AppController and make only one view.
You will use $this->render('/myview.ctp');

Best way to access adjacent components / fields

I am looking for a way to access components / field that are either in the same items array as the accessing one or even only in a same parent items array (the last one is just a option).
In ExtJS3 this was easy by simply defining a ref in the owner container but I didn't found anything like that in ExtJS4.
I know that I can use Ext.ComponentQuery() or the shortcuts up() / down() or even Ext.getCmp() but they are all not what I am looking for, cause they just executes a bunch of code while the ref was such an easy Way to do things.
Yes, I am aware of the fact that using a ComponentQuery is much more fail safe than the use of hard coded references. But I just want to know if there are some other ways to do this.
Alternately, for your case of getting the next element in a container, you can use the nextSibling or prevSibling. All components have these methods. It would be a little less walking around the DOM structure. They also allow for a selector argument.
They are described in the docs here.
Here are some tricks I have used:
//lookup by name
formPanel.getForm().findField('state');
//lookup using nextSibling/prevSibling in a fieldset or fieldcontainer
myField.ownerCt.nextSibling('textfield[fieldLabel=Description]')
Here fieldLabel property is used to narrow down field selection but you can use ANY property at all. So if you construct a field with a property ref you can then use it to select your field similar how you would use it in a ComponentQuery .

Preferred way of creating links with backbone.js

I'm trying to wrap my head around backbone.js but I'm finding it hard due to the lack of (IMO) good examples.
First of all, what is the best way of getting a link to an object.
If I want to get the edit url of an Album model I could do album.url() + '/edit', is this really the best way?
Also, I'm trying to make my application work 100% without javascript so I don't want my URLs/links to say /albums/#1/edit, I want it to be /albums/1/edit and override this in JS.
I'm thinking I create normal URLs and use jQuery.live to call router.navigate in backbone.js
I never got this to work however, when I call router.navigate('/albums/2', true) the URL changes but my show action is never called. If I refresh it's called so the route is matched.
What am I missing?
The basic answer, which is kind of frustrating, is "there is no preferred way!". Backbone.js doesn't tell you how to set up links, you can do it any way you like. I found this flexibility just as annoying as you do, at least at first.
So here's the way I'm approaching this on my current project, with the (big) caveat that this is just one of many ways to do things in Backbone:
For the most part, I don't use actual links. There's no explicit reason not to, but it means you have to keep track of a bunch of URL strings that have to be consistent. I would rather stick all the URL formatting in my routers and not deal with it elsewhere.
To open a new "top-level" view, like an editing screen, I set something that fires an event. In the application I'm currently working on, I have a global State model, and to open a new view I call state.set({ topview: MyTopView }). This causes the state object to trigger change:topview.
Any piece of the UI that needs to change when the top-level view changes has an update method bound to change:topview. When the event fires, they look at state.get('topview') and update as necessary.
I treat my routers as only marginally specialized parts of the UI - they're essentially views that render in the browser address bar, rather than the window. Like other views, they update the state object on UI events (i.e. a new URL), and like other views, they listen to the state object for changes that cause them to update. The logic that the editing screen has the URL albums/<albumid>/edit is fully encapsulated in the router, and I don't refer to it anywhere else.
This works well for me, but it adds an entirely new pattern, the global State object, to the Backbone structure, so I can hardly call this the "preferred" approach.
Update: Also note that .url(), in the Backbone idiom, refers to the model's URL in the back-end API, not the front-end URL (it's not like Django's get_absolute_url). There is no method in the default Backbone setup that gives you a user-facing URL for your model - you'd have to write this yourself.
Also, I'm trying to make my application work 100% without javascript; so I don't want my URLs/links to say /albums/#1/edit, I want it to be /albums/1/edit and override this in JS.
you can do exactly this w/ pushState. just enable it in your Backbone.history.start call:
Backbone.history.start({pushState: true})
this tells Backbone to use the HTML5 History API (a.k.a. "PushState"), which uses full URLs exactly like you're wanting.
read up on the history api here: http://diveintohtml5.ep.io/history.html
and I wrote up a 2 part series on using pushstate w/ the second part focusing on progressive enhancement in backbone, to do what you're needing:
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-1-introducing-pushstate/
and
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/
hope that helps :)

How to "bypass" constructor call if instance is not null (WinForms designer code)

When we place a component on a Windows Form, the default behavior for the designer is to serialize a contructor call in the IntializeComponent method of the form.
Is there any way to have a custom serializer output the following code:
if (componentInstance == null)
componentInstance = new componentClass();
instead of just:
componentInstance = new componentClass();
The reason is simply that the component is instantiated before the Form, and I want to pass it to one of the Form's constructors.
The component is designed to allow quick selection of properties (in the same way you add your DataBinding to Controls) at design time, but the call to the constructor in InitializeComponent() assumes I want to create a new instance when in fact, I already have a reference to it. By checking for null, then it would work both at design time and run time.
Thank you.
It's simple really - don't use the Form Designer to add your component to the Winform. Instead manually add a member variable of the component type that you are after into the underlying code (.cs) file and handle it directly in code.
Added in response to your comment
As far as I am aware, there is no way in which you can avoid this behaviour for components placed at design time. You could delete references from initialise components method, but this may be overwritten by the designer at some point.
Taking into account your comment below, then I would suggest that you have a member variable on the form (as suggested above) and then set this to refer to the design time component if the runtime variable is null or the runtime variable if it isn't.
i.e.
CSomeComponentType liveComponent;
...
this.liveComponent = runtimeVariable;
if(this.liveComponent == null)
{
this.liveComponent = this.designTimeComponent;
}

Resources