I'm writing a simple software as a service like app where each customer defines a set of configuration for a specific component. Then at runtime I need to construct a range of models based on this configuration.
My question is when should I lookup the configuration and build the array of dynamic ember objects to represent these models?
Currently I'm playing around with this inside the setupControllers function of the ApplicationRoute itself (as it's only loaded 1x when the app is loaded and then I'll have the array of models at any moment instead of waiting for them just in time later on.)
This set of configuration is minimal and the performance gains from this approach are worth it for this example. But is this the right component to load these up / create dynamic models?
My question is when should I lookup the configuration and build the array of dynamic ember objects to represent these models?
It depends of course ;-)
If you need ember to be in a loading state while the lookup happens, then setupControllers is too late. In that case consider using the model hook instead.
Do you need to do all of this configuration upfront? If not maybe push it down to setupControllers callback on a subroute.
But is this the right component to load these up / create dynamic models?
Yes - in this case I'd say setupControllers on application route is a good choice.
Related
I am trying to build a UI with left side bar having filters and right side having actual filtered data.
For loading data into the dynamic part of the UI(right side), which approach is considered better in terms of code quality and app performance ?
Use sub routes (for dynamic part of the UI)
Use separate components that load their own data (for dynamic part of
the UI)
There is not a direct correct answer for that; you can use both ways but here is a few things to consider and in the end I generally prefer to use sub-routes due to the following:
Waiting for UI to load: In case you are using separate components to load their own data; then you need to handle the loading state of the components. What I mean is; if you simply use sub-routes; then model hooks (model, beforeModel, etc.) will wait for the promises to be solved before displaying the data. If you simply provide a loading template (see the guide for details) it will be displayed by default. In case you use components, you might need to deal with displaying an overlay/spinner to give a better UX.
Error Handling: Similarly like loading state management; Ember has already built in support for error handling during route hook methods. You will need to deal with that on your own if you prefer components to make the remote calls. (See guide for details)
Application State: Ember is SPA framework; it is common practice to synchronize application state with the URL. If you use sub-routes; you can simply make use of the query parameters (see the guide for details) and you will be able to share the URL with others and the application will load with the same state. It is a little bit trickier to do the same with components; you still need to use query parameters within the routes and pass the parameters to the components to do that.
Use of component hook methods: If you intend to use the components then you will most likely need to use component hook methods to open the application with default filter values. This means you will need to make some remote call to the server within one or more of init, willRender, didReceiveAttrs component hook methods. I personally do not like remote calling within those methods; because I feel like this should better be done within routes and data should be passed to the components; but this is my personal taste of coding that you should approach the case differently and this is perfectly fine.
Data down, actions up keeps components flexible
In your specific example, I'll propose a third option: separate components that emit actions, have their data loaded by the route's controller, and never manipulate their passed parameters directly in alignment with DDAU.
I would have one component, search-filter searchParams=searchParams onFilterChange=(action 'filterChanged'), for the search filter and another component that is search-results data=searchResults to display the data.
Let's look at the search filter first. Using actions provides you with maximum flexibility since the search filter simply emits some sort of search object on change. Your controller action would look like:
actions: {
filterChanged(searchParams){
this.set('searchParams', searchParams);
//make the search and then update `searchResults`
}
}
which means your search-filter component would aggregate all of the search filter fields into a single search object that's used as the lone parameter of the onFilterChange.
You may think now, "well, why not just do the searching from within the component?" You can, but doing so in a DRY way would mean that on load, you first pass params to the component, a default search is made on didInsertElement which emits a result in an action, which updates the searchResults value. I find this control flow to not be the most obvious. Furthermore, you'd probably need to emit an onSearchError callback, and then potentially other actions / helper options if the act of searching / what search filter params can be applied together ever becomes conditionally dependent on the page in the app.
A component that takes in a search object and emits an action every time a search filter field changes is dead simple to reason about. Since the searchParams are one-way bound, any route that uses this component in it's template can control whether a field field updates (by optionally preventing the updating of searchParams in an invalid case) or whether the search ever fires based of validation rules that may differ between routes. Plus, theres no mocking of dependencies during unit testing.
Think twice before using subroutes
For the subroutes part of your question, I've found deeply nested routes to almost always be an antipattern. By deeply, I mean beyond app->first-child->second child where the first child is a sort of menu like structure that controls the changing between the different displays at the second child level by simple {{link-to}} helpers. If I have to share state between parents and children, I create a first-child-routes-shared-state service rather than doing the modelFor or controllerFor song and dance.
You must also consider when debating using children route vs handlebars {{if}} {{else}} sections whether the back button behavior should return to the previous step or return to the route before you entered the whole section. In a Wire transfer wizard that goes from create -> review -> complete, should I really be able to press the back button from complete to review after already having made the payment?
In the searchFilter + displayData case, they're always in the same route for me. If the search values need to be persistent on URL refresh, I opt for query params.
Lastly, note well that just because /users/:id/profile implies nesting, you can also just use this.route('user-profile', { 'path' : 'users/:id/profile' }) and avoid the nesting altogether.
im learning Zend Framework (3) ... I installed Doctrine because i do not want to write sql queries to learn all other stuff faster....
First Question:
So know i configured a factory that loads me the doctrine entity manager to my Controllers (with DI).
So its really simple to get my entities to my controller ... e.g in my Project Controller createAction i can easy get my user entities to show them in my project form (project <--> user many-to-many).
But know im struggling, would it be better to create repository classes and inject this to my controllers instead of the doctrine entity manager, so i can filtering etc all my entities?
Second question:
When i want to filter my projects (e.g by user)
where should i do this ... in simpler slim projects i created Collection classes and injected them all of my entities and after that i called a filter method in my collection ... but the problem there is, i just loaded all entities from my database to the collection. In larger application i think there are to many entities loaded from the Database?
Third Question (Conclusion):
When i want to load data from the db to my Controllers whats best Practice here?
Load it from the entity manager ?
Load it from a Repository (the Repository load it from the entity manager)?
Load it from a Collection (the Collection loads data from the repository class and the repository loads data from the entity manager)?
I did not thought about Pagination #all... thats what i have to do next ... but there are many questions similar to my other questions.
(I know there is a zend module for this .. but have no idea how this works.. have too learn this too)
Im thankful for every hint, meaning etc.
Answers to this question are possibly all opinion based. I would say it is all about personal preference. There is no such thing as best practice here it all depends on what you will do in your controller. On top of that you can easily get a repository from your entity-manager if you need it:
$userRepository = $entityManager->getRepository('Application\Entity\User');
A more common might be to make a custom UserService (a wrapper class) around your repository/entity-manager that you populate with the custom methods you would like to use with your User resources.
I hope this helps you a bit...
My question is: Can someone direct me in moving from controller based application to component base application?
I am building a map application for my dog training club. We are specialized in helping finding missing people.
In order to organize our training, we need an application to draw trails and add items on them etc.
I've started an app using Ember-Cli and OpenLayers-3. The application is working nicely, but I would like to move the code from controller based to component base approach.
I would like also to use more routing as at the moment, I have only one route and all user interactions are handled using actions.
I've setup a repository on github for those who would be kind enough to help me:
https://github.com/mylen/mantrailling
if you want to checkout the code and test the app localy, you'll need to modify the referer using a header mod in your navigator to use http://demo.melard.fr
You can see a beta of the website at that page :
http://recherche.utilitaire.melard.fr/beta/map
Thank you in advance,
First, we should clarify the intended uses of components, controllers and routes in ember.js.
Components are similar to Views, but they are isolated and therefore used to create reusable pieces of code, that handle the visual representation of your models.
Controllers are mainly used to decorate your models, but also to hold application state.
Routes represent you current application state. They are responsible for loading your models and to initialize your controllers.
To solve your first problem (controllers -> components), you only need to move all view related stuff, and only this, into components. Your code that decorate your model, for example the active flag of a way-point, remains in the controller. You only need to bind the data of your models/controllers to the components, via embers data binding. (http://guides.emberjs.com/v1.11.0/components/passing-properties-to-a-component)
Your second problem (use routes) is a bit harder to solve, I think. First you need to find all of the states your app currently have. After that, you should move your model loading and saving stuff into this routes.
Edit
Some references describing the problem.
https://github.com/ef4/rfcs/blob/routeable-components/active/0000-routeable-components.md
https://www.youtube.com/watch?v=QgycDZjOnIg
Edit 2
Your question is highly related to How to move ember from 1.x to 2.0, because the changes you mentioned will come along with ember 2.0.
Here are some additional links that describe how to prepare best for this upgrade.
https://gist.github.com/samselikoff/1d7300ce59d216fdaf97
https://speakerdeck.com/tomdale/ember-2-dot-0-in-practice
http://discuss.emberjs.com/t/what-is-a-good-way-to-do-this-in-ember-2-0-no-itemcontroller-no-arraycontroller/6649
You can find a lot of resources if you search for ember 2.0.
Edit 3
Here is I think the most informative source for keeping up with new Ember releases:
https://www.youtube.com/watch?v=wsydQzQF4Ww
I'm looking at creating a google maps component. But I would like it to be self contained so it will have its own model, controllers and views. So for example the component will fetch its own data from the server and I'll also be able to refresh the data when needed. Ideally I'd simply add the component to the current template that is showing, so for example: {{map-view}} and then everything the component needs to do will take care of its self.
The component will also need to listen to triggered events from other controllers as a user will be able to search for a specific location and the map will need to change its position.
Is this possible to do in EmberJS? As I haven't found anything like this, specially when having its own model. I know there is a component in EmberJS but it seems very limited. Am I wrong in thinking this?
the controller cannot have its own model all values must be passed to component. Please refer to ember docs and this Discussion
You can make a google map component and pass the location and marker data to the component. this data will get updated due to ember data binding.
so you can have something like this
{{map-view location=userEnteredValue}}
you can search for ember component talk by Kris Selden on youtube which includes a google map component good for you to start with.
updated
https://gist.github.com/krisselden/8189650
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