PDA

View Full Version : Is a Component just a more complex View?



alexmcmillan
21 Apr 2014, 2:18 PM
I'm having trouble understanding the role of Components in the MVC architecture. I get the feeling they are just a more-complex view (or a "View wrapper" ?) that work as an event proxy converting, for example "keydown" into "perform X" events for a Controller.

For example, consider a simple "document editor" app. A document consists of a list of Nodes, each of which contain a list of Chunks. This forms an (intended) structure like so:



<div class='node'>
<div class='dragHandle'></div>
<div class='hierarchy'>1)</div>
<div class='content'>
<span class='bold'>Bold Statement: </span>
<span>This is some content! But </span>
<span class='underline'>these words</span>
<span> are underlined</span>
</div>
</div>



Which would be a "correct" MVC-based approach to modelling this? So far I have:

Controllers:

App
Document
Models:

Node
Chunk
Stores:

Nodes
with the Nodes store loading dummy data from a static JSON file via proxy. (This JSON file contains Node data with a nested "chunks" array because I couldn't get a Node view using a Node model to display its chunks when they were loaded into separate stores, regardless of any "hasMany" or "belongsTo" relationship configs I tried on the models).

I have tried making Views, but they require tpl and itemSelector fields. This seems logical, but I can't "nest" an entire Chunk view inside a Node's tpl so I moved towards building a Component.

This is turning into a nightmare, as the majority of guides/tutorials I've found seem obsessed with simply dumping data into a Grid, never explaining how to build an html structure like that above.

Currently I have a Node component which extends Ext.container.Container, and contains multiple Text components, which extend Ext.Component. For some reason, Ext is positioning everything absolutely, which means when these contenteditable: true text components are modified, their content is hidden under the other components on the page which do not move in response to the previous containers height change. Aargh!

Any direction/advice/help would be much appreciated. I have been through almost all of the tutorials and examples provided by Sencha and watched tons of videos but there seems to be very little that helps explain this kinda of thing.

evant
21 Apr 2014, 3:52 PM
You're getting it a bit backwards.Ext.view.View extends Ext.Component, not the other way around.

You can just build a component with markup:



var component = new Ext.Component({
html: [
'<div class="foo">othermarkup</div>'
].join('')
});


Or slightly more complicated:



var component = new Ext.Component({
tpl: [
'<div class="{customCls}">{otherThing}</div>'
],
data: {
customCls: 'x',
otherThing: 'y'
}
});


A view is (somewhat) similar to the above, but backed by a store for many records. It also adds various useful events.

alexmcmillan
21 Apr 2014, 4:13 PM
:facepalm: Thanks, that make a lot of sense. Looking at the inheritance tree of Ext.view.View I see it now... I always just assumed Ext.view.View was a core class, a lot like Ext.data.Model and Ext.app.Controller.

I really can't figure out whether I should be building a Node Container and a bunch of Views representing different types of content, or a single View that can be rendered as a whole thing.

Basically, I want to be able to create a Node and tell it to render, then have it render some HTML, then all its contained items, then some more HTML. Could you offer me a gentle shove in the right direction? I would really appreciate it.

evant
21 Apr 2014, 8:17 PM
The description is a little vague. If you want to "mix" markup with items, then you'll need to wrap the markup in components.

skirtle
22 Apr 2014, 10:36 PM
For more info on building the HTML of a component:

http://skirtlesden.com/articles/html-and-extjs-components

Whether you choose to use a single component or nest multiple component inside each other is usually just a trade off between convenience (multiple components) and performance (one component).

Your description of your nodes sounds a little bit like nested panels with docked items for the HTML above ad below. However, panels are expensive so this won't scale if you have dozens of nodes.

If you go with the multiple component route you're going to have to embrace the layout system that comes with it. Absolute positioning on some elements is a part of that. If you're making changes to a component's markup without using the built in methods it won't know to re-run the layout. Calling updateLayout should fix that.

Using contenteditable is a bit cheap and cheerful. I'd be more inclined to build something that swaps in an ExtJS textfield on click. Maybe using an Ext.Editor or building a manual equivalent.

The renaming of DataView to View in ExtJS 4 has caused no end of confusion...