I've been learning Ember over the past few months, and with the beta release of 2.0 I've working on following the "data down, actions up" structure with my components. Unfortunately, this means actions are getting thrown all over the place and it's not very appealing to define them in every component and every template, only to be like, "yes, keep bubbling this up to the controller please". Is there any way to pass actions in groups or nest them so that in my handlebars templates I can just use something like {{my-component myActionGroup=myActionGroup}} and then unpack them within the component definition? Or maybe a setting to tell ember to allow component actions to bubble?
The component I'm working on right now is for nested sets, so I'm ending up with really deeply nested components. Keeping them all straight is pretty awful and doesn't seem very DRY to me since changing the name of one requires changing the associated one in close to ten other files. I know I could just reroute one to another in the handlebars template but then they become a mangled tangled mess. Are there any other options? Thanks!
Related
Is there a way to avoid a template destruction when changing routes in iron-router? Since my template is all reactive but a little bulky, I want to keep it "behind the scenes" (in memory) while going to other templates and just show it when the route come back without re-creating everything (it is builded through several mongo/minimongo collection queries that add delays to the user experience).
I can think in some workarounds like hide/show DOM objects (awful solution) or make my route a home route and nest all other routes inside (not so good) but I wonder if there is a native way to accomplish that.
Thanks in advance.
I have just started to use Flux in my project, but I find it difficult to reuse a component (or have multi instances in different places) when it's complex. By "complex" I mean a component includes some smaller components and may involves some interactions of changing some data. For example, a component containing a list, a adding new input and button.
I can come out with two ways of solving it:
Passing all functions that handling change events by props from
parent, so the component will not know which action is really
called. In this way, there will be a lot functions passing down for
different levels' components.
Passing an 'identifier' object when calling
action. In store it will access corresponding data located by the
'identifier'. This way there is added logic and parameter
"identifier".
I haven't found a best way of handling this, basicly because store and action in Flux are singleton. Is there any more elegant way to solve this? Thanks!
I come from a Backbone / Marionette background and have been working in React for a few weeks now. A lot of people say you should pair React with something like Backbone or Ampersand.js, using React as the V and Backbone / Ampersand as the "M" and "C" in the classic MVC model.
However, the more I think about this, the more I wonder if it's really necessary. In Backbone / Ampersand, the model's main purpose is to track state, and "tell" views to update when the model's state changes. Of course in React, the view takes care of this responsibility via the view's props and state, which seems to make a full blown Backbone / Ampersand model unnecessary and duplicative.
What am I missing?
First, let's define model in MVC terms. The following is from Wikipedia.
[...] the model, captures the behavior of the application [...] independent of the user interface.
The model directly manages the data, logic and rules of the application. A view can be any output representation of information [...] multiple views of the same information are possible [...].
The third part, the controller, accepts input and converts it to commands for the model or view.
In React you inevitably will create View+Controller components; much like angular, knockout, and most other JS application frameworks.
Why models?
While you could also throw the model into the component at this level, it turns out to not work well in practice. You have problems like overfetching (and other optimization limitations), difficulty testing, no separation of concerns, and it's difficult to see what the component actually is until you mentally separate the controller behavior from the model behavior.
So, backbone?
If you have this code, and you want to make it better, you'll eventually end up with models. It could be backbone models, or it could be flux stores, or it could just be simple objects with functions that call $.ajax.
It makes little difference what kind of models you use, but you do need them.
MODEL ALL THE THINGS
Woah! Hold on there. Models aren't free. Every time you use a model you're crossing the abstraction boundary, and leaving component land. It's an imperative action in a declarative system, so we need to keep things predictable.
Most of your components are pretty dumb. Props, and maybe some UI state. You have controller components ("View Controllers"), which are 100% tied to your model layer, and you have the rest of the components which are (ideally) 0% tied to your model layer.
What you seem to be describing in the original question is a small application where you have one of these controller components. However as these grow, you need to coordinate between them (not fetching the same user twice, for example). You nest these controllers inside other controllers to build an application. The model is the glue.
You can think of a React component as a functionally pure function that takes props and state as input arguments. Its render() method's job is to produce and returns a (virtual) DOM element or JSX (syntactic sugar) based on props and state. Backbone still "owns" the model. When the Backbone model changes via user inputs or socket events or whatever, setState() can be called (add some magic here) which causes React components to render again. The point is React component does not hold the state. This is NOT to say that one must uses Backbone with React as React is simply a rendering library.
Update: In react-future, it's very clear that render() should be treated as a pure function. It takes props and state as input arguments and its job is to produce a JXS, so no need to refer to the this keyword.
https://github.com/reactjs/react-future/blob/master/01%20-%20Core/01%20-%20Classes.js
So trying to get my hands dirty with KnockoutJS 3.2. I've read the docs and I've successfully implemented components within my current project. I don't use an AMD, so I'm just using script elements to hold the views.
My question is: If i'm not using the asynchronous loading features, is there any real practical difference to using components rather than templates?
General description of both
As stated in the other answer, a template is only a piece of HTML which can be bound to a viewmodel, or viewmodel section. And a component is composed of a template, and its corresponding viewmodel. Besides, this viewmodel, apart from observables can include some simple business logic, and functionality to communicate with the server.
Coupling and encapsulation
Another important difference is the coupling. A template it's bound to the main viewmodel, and its bound to the main viewmodel's observables, so it's highly coupled to the viewmodel: a change in the viewmodel will break the template, and viceversa. So, if you're reusing a template in several places, and you change it, you have to correct the corresponding viewmodels.
A component is bound to its own viewmodel. It's only coupled to the main viewmodel if there are parameters provided from it. This means that you can easily change the component template as well as the component viewmodel, and, if there are no parameters, or you don't change them, nothing will be broken.
So using components helps in decoupling and modularizing.
Communication between main viewmodel and component
The last section is a double edged sword: if there is a high interaction between the main viewmodel and the template or component, it's much easier to use a template, because all the logic and properties are held in the main viewmodel and the interactions are easily implemented. If you used a component you'd need to provide complex parameters, or even make something to allow the component to expose functionality to the main viewmodel.
Polymorphism
It's not strange to have some parts of an application that require different behaviors and visualization to solve the same kind of task. For example, let's imagine you have to implement a payment system in your application: if you accept for example paypal and credit card payment you have two different visualization and functionalities. If you used templates, you'd need to have the particular implementation of each payment system in the main viewmodel. If you used components, they'd share a common interface (parameters) but each of them would have its own implementation. If tomorrow you had to include a new payment system, it would be easy to implement a new component with the common interface.
NOTE: pay attention to the last paragraph
Binding
In the case of a template the binding it's not done at the template level, but inside it. I.e. each element inside the template must be bound to observables of the main viewmodel. In the case of a component the binding is much simpler: at most, it requires the component name and the parameters, if they exist.
Component registration and custom tags
If you register the component you can use custom tags. This makes the views more easyly readable and understandable: instead of specifying the component name in a binding, you use a tag with the component name, and parameters are passed as attributes.
Dynamic loading
If you use templates you have to dynamically load them by yourself, and, as this is an asynchronous task, you'll have to take care of using the template only when it's already available. That's way in most occasions you'll use inline templates. This is not good if they must be reused in several places.
If you have used some AMD implementation, like require.js, and you understand the benefits of this technology, you'll be happy to know that you can easily use AMD to load component templates and viewmodels. One of the advantages is that you don't have to worry about the template or component being available when you need to use them.
Testability
No matter if you do manual or automated tests, it's much easier to test a bunch of independent components, one by one, that to test a complex viewmodel with or without templates.
My choice
So far, I've exposed facts about templates, and components, and I've tried not to show my personal preferences. However, in this last section, I must say that in most situations I prefer to use components for their advantages:
modularity
low coupling
easy reuse
testability
binding syntax
(optional) dynamic loading
However, templates are also a better fit on some occasions
The last paragraph have to do with big applications. If you're dealing with small applications or simply enhancements of interfaces rendered by another technology (like ASP.NET MVC), you'll probably get none of the advantages of using components. So, you don't need them.
There are other cases when it's not worth using components. For example, if you have to show a list (JavaScript array) of items which have different properties which must be shown in a different way, it's easier to use templates. Note that the choice in this case is because each of the instances doesn't have a complex viewmodel with a lot of functionality, but a simple bunch of properties. In this particular case it's not only not worth, but it can also be counterproductive to use components.
You can understand this last example as polymorphism. But, in this case it's nearly "visual" polymorphism. I.e. each kind of item must be shown in a different way, but there is no need to implement any special logic in each of the components.
However, even in this case, if the templates are complex enough, or must be used in many different places, it's also much better to use a simple component that includes the template as well as a parameter that receives the whole item. So, even in this case, it's not a bad idea to use components.
If you'd read this far, thank you, and I hope you have some criteria to help you choosing the best option.
They aren't completely different. Components are made up of templates (html) and data/logic (view model i.e. JavaScript). When you have a modular view you want to attach a view model to you can utilize components. Here's a link discussing components a bit more: http://www.knockmeout.net/2014/06/knockout-3-2-preview-components.html
I dare call myself a backbone hacker. I know what the framework can do, and where its limitations are. I also have some experience with a few templating frameworks.
I've seen many tutorials where people explain how to create complex and nested views, and most of them construct it kinda partially using templates, and then within the render method of the parent view, in order to combine the templated child views
To me, this makes no sense why one should deal with the layout rendering, in the declarative code. Coming from Flex, I was taught to never do that. I always left the layout descriptions and variable bindings to the markup, and then the event handling to the declarative (View instance) code which uses this markup.
None of the templating frameworks I tested, however, allows the creation of complex markup, with nested views. One cannot really invoke a template from a template and thus instantiate a View object. This seems technically possible, especially using the data attributes, where we could specify type names.
Then, all the render method of the root level View class has to do is turn this template into HTML markup, then find out what the types of the child objects should be, create a child view instance for any of them, and keep further, in case those child objects should have child objects themselves. Every view is given a model context. Basically all the boilerplate steps that we deal with all the time, but automated at the Backbone.View level.
Anyone else thinking about this? Why does no one seem to be using this?
It should be noted that it is not necessary to use render at all and it is mainly reserved for re-rendering after changes to code has been made. You can bind views directly based on CSS selectors (see the docs for this).
Additionally there is a model binding extension for Backbone which greatly simplifies data-binding and reduces the 'manual' labor required. You might want to check it out.
http://github.com/derickbailey/backbone.modelbinding
Finally I will say this about rendering parent-child relationships. Do not call the DOM in a loop. This is incredibly inefficient and at least one reason people will build up parent-child relationships only in the parents render method. Having each child render itself using say jQuery will result in a lot of work for the browser (if you don't notice this in a modern browser try it in IE8).
I agree that instantiating child views in the render method makes no sense. Although I'd be hesitant to fully automate the process because I often want to pass in additional arguments when initializing a child view, eg:
var childCollection = someLogicToCreateTheChildCollection();
new ChildView({
collection : childCollection
});
So, what I end up doing instead is creating any child views I need in initialize and then in render I render the template and assign the child views to elements in the DOM.
This way my render function isn't the one declaring DOM order (like a lot of examples show by appending)—the template sets the DOM order and the render function just setElement().render()'s the child views.