I'm trying to wrap my head around Twitter flight. Lets say I have a Program page, it has 16 elements dealing with managing a program, CRUD operations, AJAX requests etc... Using twitter flight, do i need to create a component for each and every node element or for the Program page and attach each element to a function in the Program component?
A component is instantiated for each element you attach it to. If you have a list of DOM nodes, you can call .attachTo on each one and instantiate a set of components for all the nodes.
You don't have to attach a component to every node. You could have a single component attached to the document which does everything, but it makes sense to break that down in to smaller pieces of functionality. IMO, a component should represent a feature.
For example, you may have a component which communicates with an API via ajax, another which handles submissions for a particular form, another which manages the content of a list. Just how much a single component does is up to you. For the sake of portability, reusability and ease of maintenance it makes sense to keep components small and well-defined.
Saying that, you probably don't want to make lots and lots of tiny components. I wouldn't want to create one for every item in a list, but I might create one for every list on a page.
A single instance of a component can be attached to a DOM node. Components have access to the full DOM tree extending from their root node.
Related
I'm creating an app using Nodejs and Vuejs 3. In this app I have made a sidebar that gets all links from a routes file and present them. This sidebar consists in a component that parents a list of other recursive link components.
Since the links are recursive and many, I find it hard to deal with class toggling (active, showing, collapsed, etc.) on each of them and relate them to one another (if one is active the others shouldn't be) using only Vue. Should I use querySelector or any frameworks such as JQuery to handle them or should I try to stick with a pure Vuejs approach?
Edit:
I don't want to gather the community's opinion on it. My aim is to understand pragmatically why I should or shouldn't manipulate the DOM "outside" of Vue.
If you're using Vue then let it be in control of the DOM; mucking around directly will only create conflicts and woe.
(The same applies to other SPA frameworks such as React and Angular.)
The main reason not to touch the DOM is that Vue works by modifying the DOM on its own, and expects to have complete control over it: when rendering components the framework is removing old DOM elements, adding new ones, updating event bindings, etc; and a lot of it is optimized to only update the DOM nodes that need to be updated.
If you go in there and start making direct changes that Vue doesn't know about, then it's likely that your own changes will get overwritten by Vue the next time it needs to render, or that your changes will overwrite bindings that Vue is depending on.
If you're very knowledgeable about Vue's lifecycle and know how to control when it does and does not render, it is possible to work with both together -- but even then it's still not a great idea. Vue and jQuery do very similar things, but in utterly different ways. In jQuery you build up the page and then use DOM traversals and event handlers to modify it; everything lives inside the DOM. In Vue you build up a bunch of components that manage their own state and rendering; the DOM is basically a side effect of the application state.
By trying to use both together you lose most of the advantages of each of them in isolation, and introduce a lot of complexity in having to manage two competing theories of state and render management (not to mention dealing with communicating data between them). Every time I've contemplated embedding a jQuery widget inside a Vue app, it's turned out to be much easier to just rewrite the widget in Vue directly.
This does mean changing a lot of habits about working with the DOM that you may have built up from past jQuery work. It sounds like you're trying to draw the whole DOM and then build your control structure into it afterwards, which is a natural way to think if you're used to jQuery; in Vue you'll want to build all of that logic into components so the framework can do the work for you. I'd suggest making one Vue component for a link that manages its own state for open / closed / active etc, that recurses to its children only when "open". Then just call that once with the top of your nav data instead of trying to manage the whole tree directly after the fact as you would in jQuery.
Say I have a component that contains functionality to send PUT requests to my backend. Normally, these requests are triggered by the user interacting with this component directly. Let's call this Child.
A different part of my UI contains a collection of these elements rendered in a parent component. Let's call this new container Parent.
I want Parent to have a common button rendered next to the collection of Child components that lets my user trigger PUT requests from all Child elements in one go.
Currently, I save refs of each Child element as I render each of them in Parent. When the user clicks the common button rendered in Parent, I have Parent iterate over each ref and invoke the function in each Child that triggers the PUT request. Is there a better way?
Yes, there is a better way. You should lift your state up to the nearest common ancestor that needs to access it. In this case, you have data in each Child that needs to be accessible within the Parent. You're trying too hard to make Children completely independent entities which are disconnected from their container.
Instead, I'd suggest rethinking the structure of your app so that the data lives inside of Parent or another ancestor as state, and that ancestor simply passes it down to each Child as props for rendering. The function that does the PUT request can optionally also live inside of the ancestor and be handled with a callback, or - depending on the what feedback needs to happen or not happen from that callback - simply be a utility function or service which is shared across components.
Edit: this is one of the core concepts of React and is called "top-down data flow". From the React docs:
There should be a single “source of truth” for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the top-down data flow.
How to get component handler in Ext Js?
what are the different ways to get them like
this.lookupReference('ref-name-of-class')
this.lookupReferenceholder('class-name')
this.findParentByType('name-of-xtype')
Ext.ComponentQuery.query('alias-or-id')
Ext.getCmp()
this.up()......
this.down().....
Can anyone list all of them?
Gloabal IDs and Ext.getCmp() is a bad practise. It's slow and colliding global IDs will break everything.
container.getComponent() is also a bad idea. If nesting changes, everything will break.
parentComponent.query() should be used when you want to get multiple child components which are relatively close to the parent. If you want to get a single component, you should use down() method instead. There won't be a big performance hit if the child component you are searching is pretty close to the starting node.
lookupReference() or just lookup() is recommended right now but it will only work within single view or viewController class.
I am new to Angular in general and starting in earnest with Angular 2, so I want to find out if I'm not thinking about this in the right way yet.
A "panel" is a page of content in my application. I'd like to use a base panel component to provide common UI and functionality to specific panel implementations that derive from it.
I'd like for the base panel component to have templated content that wraps the template provided by the derived component- this would, for instance, provide a standardized header whose content is provided by the derived implementation and allow for the child component to supply the page content itself.
The ultimate goal is to make it as easy as possible for developers to create new panels without having to worry about rendering the common parts, so that consistency can be enforced.
Also, I want for the developer to be able have two-way binding between base variables/properties that are programmatically set from the derived component and the corresponding elements that are rendered by the parent template... (in addition to the elements in their own child template).
Is this doable? Or am I thinking about this in the wrong way... not sure if I'm in an Angular state-of-mind yet.
As I've been working on this, I'm starting to think I may need to adjust to creating reusable components (like PanelHeaderComponent) that the developer would compose within their panel implementation rather than inheriting from a base for common UI... However, I do need for the container for all panels to be centrally managed somehow.
Want to be sure I do this the right way. Thanks!
I believe a valid approach is, like you said in your last paragraphs, to componentize your application.
Basically: Create reusable components for the different parts of your application (ie: Panel Header with Buttons with a certain style)
If you want different panels that will use the same header, you can then reuse that Panel Header in all of your your panels.
It would be analogous regarding buttons, and any other control that you want to use. Define your component, then reuse it everywhere, then reuse the reusable, composite components that you defined.
Important Note: As of now, and as far as I'm aware, there's no Visual Inheritance between components, so in order to simplify your job, you might want to use sass to define the styles and take advantage of #imports in order to DRY.
I'm aiming for a decoupled UI architecture. I want the carousel and pagination components to be separate from each other; but with the pagination able to listen for changes on a uiCarouselMoved event.
Example: http://jsbin.com/uQadehI/1/edit?html,js,output
The problem arises when I have two instances of carousels and pagination respectively. I'd like to be aware of the best design pattern within Twitter Flight to handle a 'bridge' between the Carousel and the Pagination components, without relying on irrelevant logic such as DOM tree structure, and preferably no hard-coded IDs.
So, is it possible to know which pagination to updated, based on the source carousel?
Creating a pagination mixin and mixing it in to the carousel would seem to make sense.
Another option is to use the DOM to provide structure. By attaching an instance of pagination and carousel to the same DOM node or tree, you create a non-declarative relationship between the two.
Alternatively, generate a unique ID (using, for example, _.uniqueId http://underscorejs.org/#uniqueId) and pass that with the data from the carousel. This can also be included in the response, allowing components to determine if they are interested in global events.
TweetDeck uses all three of these methods in various instances. Using the DOM for structure requires no extra boilerplate, though it is also the most implicit relationship. Using IDs is very specific but requires extra boilerplate in event triggers and handlers. Using a mixin requires no boilerplate and is very specific but does create a dependency, which you may want to avoid.
I would make pagination and carousel both mixins, with_carousel and with_pagination respectively, instead of individual components. This will allow you to use both within the same component, and attach that component to a new outer level dom node. This will allow you to listen for the uiCarouselMoved event locally instead of attaching the listener to the document.
An example is here:
http://jsbin.com/iZeLABAW/1/edit