I'm looking for a way to get multiple independent routes, managed by the url in Ember.js. The Goal is, to get a Page that shows Persondata and Personrelated data on the Same Page. Here is a Mockup I created for better understanding:
https://www.dropbox.com/s/carcorg1ox0qjgd/Mockup.png (not enough reputation to post images, sry!)
I imagine a Start-URL like:
"#/person/123/Persondetails/Audi/Vehicledetails"
The Idea is, that I can change from Persondetails to Adresses without affecting the Bottom Part of Vehicledetails. The new URL should look like:
"#/person/123/Adresses/Audi/Vehicledetails"
And vice versa, changing from Vehicledetails to Engine, but stay on the Adresses route for Persondetails. The new URL should look like:
"#/person/123/Adresses/Audi/Engine"
I've already found an interesting thread to start with, but it shows only level of the dynamic Part of Routes. I'm experimenting with the router for a few days now and feel kinda stuck. Is it even possible to acchieve what I want with Ember?
I'd be very grateful for every little hint you can give me!
Unfortunately the router doesn't support this type of architecture.
It's possible someday you could hack it in with query-string params, but you'll lose a lot of the built in functionality going this route.
Ember routing design. Desktop like routes
Related
I know this question might seem a little duplicate but the other version of this question is old and some of the content (such as Views) aren't even a part of ember anymore.
I'm about 4 weeks into my internship as a front-end developer working with EmberJS. I still don't understand when it's better to use the route over the controller or vice-versa. It seems to me that every action in the route can also be used in the controller.
The one recent thing I heard was that ember routes should be stateless where as controllers should be stateful.
What is the current state of controllers and routes. When should one be used over the other?
Consider the following example to understand the state of a controller (or route, or anything), in simple terms and in current context -- lets say you have a page (like a form) with three tabs; each tab can be considered as a state - it would call different components based on the state (or the tab you are in). Now if you would happen to go back for some reason, and hit the form link again, you would see that the state would remain the same. (if you were on tab 2 when you hit back, on returning to the form, you would still be on tab 2).
So to maintain these states, controllers are the way to go, since they are singletons. Route would have lost that information, and started fresh. So basically your variables/objects in a controller would define the 'state'.
Route-actions can be as easily used as controller actions- see https://github.com/DockYard/ember-route-action-helper. So if your template for this route is just using model as the object directly, and you don't need to maintain the 'state', you can pretty much do without your controller.
But if your template was using variables which needed manipulation, you would need controller.
Hope this helps!
I have two models in my route, people and appointments.
My components are:
people-list(parent) and people items(children),
appointment-list(parent) and appointment items(children).
In my route, I want to list appointments based on checked people (checkboxes in each people item). How would I tell my route about all the checked people items?
Also, I have a datepicker on the route, I want to display appointments based on date, how would I go about doing this?
Again, I want to use pure COMPONENTS, no controllers and I also do not want to make a property in my people model called isChecked as this would never be a real attribute in a real database table.
Help is greatly appreciated. Thanks.
I think it's counter-productive to avoid controllers completely, as what you describe is one of the things that controllers are about, holding on to state.
The route is responsible for dealing with the URL segments of the application and setting up the template/controller/model combo, but it doesn't know anything about them, so it'd be a bad place to keep that data in.
An alternative is to use a service, which is possibly trickier than relying on the controller.
What you should avoid is the proxying behaviour of the old ObjectController and ArrayController (gone in 2.0), and don't rely on the controller being a singleton (routable components won't be singletons).
I seem to be getting more and more confounded at what appears, on the surface at least to be pretty basic architectural questions regarding building ember apps.
Which Controller type?
In the last month or so, I've seen people implement controllers through Ember.Controller, Ember.ArrayController, Ember.ObjectController, and Ember.ArrayProxy. Removing ArrayController and ArrayProxy (due to them being identical), what are common use cases between each type?
So far, i've been able to gather that:
ArrayControllers/Proxies should be used when you have n elements within the view you intend to control
ObjectControllers should be used when the view is simple enough to maintain it's state in a single object, or be a single instance of a model's object.
Controllers --- ? No idea.
What are some basic differences between the controller types? There doesn't seem to be concrete information on when to use which, and for which use case. The API docs are good at telling me the nitty gritty of each of them, but not WHEN to use each.
The relationship between a View and a Controller can be baffling
When a View is connected via a routes ConnectOutlets function call, what exactly happens between the controller and the view?
Are events tied into the view itself (which seems to be the case) and if so, where on earth do you interact with the controller singleton to perform CRUD-esq things on its properties? this.get('controllerName') doesn't seem to do the trick, and nearly each post or tutorial or code sample out there does this a different way.
Models that aren't
I realize that Ember Data looks to help solve some of the more irritating parts of dealing with data and keeping it in sync, but at a larger perspective, in the concept of "MVC", ember doesn't really seem to have a Model of any kind. It's just some object that gets subclassed from a specific thing and then tracked....somewhere? Somehow? Magical?
#trek sufficed that an Ember.Object could manage ajax'ing data and handling state on the client just fine, but if you look at something like the todomvc.com ember app, it uses a localStorage paradigm that is COMPLETELY different in implementation then everything i've looked at.
How EXACTLY should the 'Model' part of the MVC equation be done here?
Views make me want to murder children
There seems to be a significant number of ways to construct a "view" in terms of displaying markup to a user.
ContainerViews, using subviews / childviews
nested outlets
Handlebars templates + an outlet
using #each foo in controller
Injection through literals (template: Ember.Handlebars.compile('<h1>foo</h1>') etc)
With that in mind, what's the 'proper' way to build modular UI components with ember? This more than anything is a major pain point for the adoption of this framework for me.
I love the direction that Ember is going with application development on the web. The concepts seem simple, but the verbosity is that of Objective-C (which makes sense given it's lineage) but I swear to god I feel like i'm fighting the god damned framework more than i'm actually working on my application. The verbosity of the syntax and the lack of structured documentation outside of API documentation (which lets face it, 300k of javascript is a significant amount of code to throw some breakpoints down and try to debug your issues).
I realize the challenge that you guys are up against, but hopefully this at least makes you pause for a minute and think of how you could make life easier for the incoming developer who's worked with other frameworks (or hell, even worked within an MVC framework, like rails or django or backbone or angular) and say "this is how we think ember should be used".
Take some of the opinionated software design decisions and apply them toward the community. We'll do nothing but be cheerleaders for you if you do it, promise.
Please don't hurt any children. AFAIK the ember-core team are all over 18, so any ember-view-related frustration is clearly better directed towards adults. With that in mind...
Which Controller Type?
You've got the "what" right, but maybe missing the "why". Controller can be a little misleading, especially coming from rails. Think of these controller singletons as representing the state (in-memory) of your application.
Which kind of controller to use depends on what is required for that part of your application. For example, a back-of-napkin sketch for any app might have a topnav, postList, postDetails section. In ember, each is represented by one or more view/controller pairs. In this app I would expect to see ApplicationController and NavigationController extending Ember.Controler while postList would extend ArrayController and PostDetails would be an ObjectController.
You could do it all using just Ember.Controller but ObjectController and ArrayController are really useful for wrapping model data. Any non-trivial ember app will probably use all three.
The relationship between a View and a Controller
A controller's job is to provide the context in which the view will be rendered. Ideally you'd like to keep logic out of views, so a typical controller will have lots of computed properties to do things like:
transform data from the underlying model objects
sort/filter/select a list of objects
reflect application state
whats the deal with connectOutlets? This is where you should be using the requested route/context to decide which views/data should be plugged into the outlets of your application. The controller's connectOutlet method has a bunch of magic to make it easy, but maybe too much magic. What happens (afaik) when you call: parentcontroller.connectOutlet 'child' is
Ember creates an instance of ChildView
The {{outlet}} handlebars helper in parentController's view is bound to this childView instance
The childView is rendered with the router.childController singleton as it's context
where to do crud stuff?: Typically in an action on the router. This seems crazy at first. Think of ember router not like rails but as a stateManager that just happens to also handle routing. In near-future router API will change to make this more clear. Anyway, use router actions to do things like create model instances, commit/rollback transactions and trigger state change. This is easy to do if you use the handlebars {{action}} helper for links/buttons as it targets the router by default.
Views on the other hand should have logic for "reacting to browser events" - that means really low-level stuff like show/hide something on mouseover or integrate with 3rd party libraries to do effects and animations.
You might find this screencast helpful in understanding how to do CRUD-esq things:
http://blog.bigbinary.com/2012/09/06/crud-application-in-emberjs.html
Models WTF?
Agreed in Ember any object could be used as a 'Model'. I think #trek does a good job of demonstrating how one might accomplish this via Ember.Object. This works great for a simple app, and six months back maybe would've been your best bet as ember-data was really immature. I'm not clear on the history of ember's todomvc app, but for sure it was written months ago. For sure it should be updated, but meantime I'd not recommend using it to learn about current ember best-practices.
Instead, you should go with ember-data. Over the last few months it has really evolved and should be the default choice for any new, non-trivial ember app. #tomdale just gave a great presentation on this topic, I'd recommend having a look: https://speakerdeck.com/tomdale/ember-data-internals
what's the 'proper' way to build modular UI components with ember?
For building modular UI components:
ContainerViews, using subviews / childviews
Injection through literals (template: Ember.Handlebars.compile ...)
For building an individual application:
nested outlets
Handlebars templates + an outlet
using #each foo in controller
Building modular UI components is a totally different problem than building an application. Ember.View and it's subclasses were designed for this purpose. You can easily extend/combine them to compose widgets with custom behaviors and share those widgets across applications.
At least that's how i've seen it done. If they are for internal use could also reference handlebars templates instead of object literals, but if planning to distribute the object literals approach seems best.
A great real-world example of this is the ember-bootstrap project. I learned a lot about working with ember-views by reading through that project's source. http://emberjs-addons.github.com/ember-bootstrap/
TLDR
Pick controller that maps to type of data being represented
Controllers provide context for the view and remember application state
Use ember data for your models
Use subclasses of Ember.View to make components
Be nice to children
Apologies if this has been discussed before, have searched and searched but didn't find anything useful :)
But here goes.
We're currently in the process of rewriting a portion of our webapp. Our app is rather old and therefore suffers from some rather cowboy'ish approaches to programming, conventions and urls.
What we're looking for is a simple clean way to design our views and urls so that we can maintain both easier in the future.
The problem is; as of now our urls.py file for the main site is one big mess. a lot of urls that point to a unique view that only does one thin.
Ex. list_books/, edit_book/ etc.
when it comes to specific formats etc. we have something like list_books_json/
(these aren't the actual urls though, but just used to prove a point since the real urls are much worse)
What we want to do now is clean it up a bit. And we we're wondering what the best way to get around it would be??
What we have thought of so far(after reading a lot of things on the subject):
We've thought of designing our urls after the following pattern:
domain/object/action/
so the urls for the apps "staff" site for changing books in the app would be:
staff/books - to view all books (GET)
staff/books/ID - to view one books (GET)
staff/books/new - to create a new book (POST)
staff/books/ID/edit - to edit specific books (POST)
staff/books/ID/delete - to delete specific books (POST)
The thought was then to have only 1 view, views.staff_books() to handle all these actions when dealing with books through the "staff" part of the site.
so that staff_books() checks for ID or a certain "action" (edit, new, delete etc.)
The result would be fewer, but a lot larger views that have to handle all aspects of staff/books. Right now we have a ton of small views that handle only one thing.
Does this makes sense, can you see potential problems? How do you guys go about it??
One place where I think we're lost is in regards to formats.
Where would you put ex. the request for returning the response in json?
we're wondering "staff/books.json" or "staff/books/ID.json" etc. and then keeping all the json logic in the same "staff_books()" view.
So thats it basically. I'm sorry the question is a little "fluffy"... We basically need some examples or good design advice as to how to structure urls and views.
Kind Regards
pete
As an extension (and solution) to your problem I would suggest to use the strategy pattern. Since you already have a structure and the only thing that differs is "how" it is supposed to be carried out, this pattern fits your problem perfectly. What I mean by that is the following:
Create a view which is your entry point to your application with functions named as your url-based functionality (edit, new, delete etc.). I.e where your url.py determines where to go from there.
Create classes which do your stuff based on your domains etc. Lets call them Book, Calendar etc for now.
Implement functionality of those classes, like edit, new, delete etc.
in your view then, determine what class to instantiate and call the corresponding function, e.g in View.edit() call domain.edit()
I think that should do it ^^
Hope it helps :D
I should start by saying that I'm a complete Ember.js noob (and MVC JavaScript Framework noob in general).
I'm trying to figure out how the Router and StateManager work together. I've cobbled together an example from various places on the interwebs, you can view it here:
http://jsfiddle.net/zdfs/qsAxZ/1/
So everything on first load seems like it's working. But there are pieces of the function that don't seem to be behaving properly. I want the CSS classes that I attach via the action links to actually be a part of the application state, but I have something messed up somewhere.
You can duplicate the problem by clicking "webcam" or "screensharing". The link will highlight. When I reload the page, the state is correct, but the highlight is lost. I'm doing something incorrectly, but I don't know how to fix it.
If I try to move the actions into the StateManager, then the router.get("applicationController") reference is lost.
I also can't do something like sManager.send("goHome"); - problems occur.
Some remarks after reading your code:
Is there a reason why you did split your code between a Router & a StateManager? In the current canonical form, your states should be classes of Ember.State, located inside the router.
The connectOutlet method should be called from the connectOutlets state's hook, not the enter one.
The event handlers in the router get the router instance in first parameter, not a state (cf. goHome, viewWebcam & viewScreen)