Does ember require routes? - ember.js

I'm writing a feed reader plugin for wordpress.
Feeds have entries. Click on a feed, show the entries from that feed.
I have that working in older versions of ember, but when I try to upgrade to the release candidates it seems like we have to have a router. Defining routes etc is turning into a major headache and I'm wondering if I can just use the databinding that I came to ember for.
Is there a way to just use the databinding to controllers and models without having to go through the whole router business?

Is there a way to just use the databinding to controllers and models without having to go through the whole router business?
Yes it's possible to use ember without the router. It will still be there in background but won't cause any trouble. Just set location: 'none' and then customize App.ApplicationController, App.ApplicationView and application.hbs as necessary. You may find it is still useful to customize the App.ApplicationRoute as well.
App.Router.reopen({
location: 'none'
});
FWIW #commadelimited is right, checkout the Peepcode video and consider taking advantage of the router.

Ember's routes have smart defaults so if you're app is pretty basic, you may not need to touch the routes.
location:none simply makes it so you're url doesn't show state changes, which can be useful
If you're app doesnt have any use for routes(maybe it's super small) you can simply put everything into a controller on your initial state/route and not worry about it.
But even if you have a simple setup of a few states:
App.Router.map(function() {
this.resource("index", { path: "/" }, function(){
this.route("stuff", { path: "/stuff" });
this.route("otherstuff", { path: "/otherstuff" });
});
});
the routes default action is take care of the magic behind that, so you shouldnt need to do anything :)

Related

ember 2.17: calling a jquery document.ready() function

I am really new to Ember, which I am asked to do and well, love to learn. Basically, the current project uses Gentelella Admin Dashboard. I being trying to get the dashboard to load properly but failed.
After I login, I get redirected to /dashboard/ route, which basically loads the main dashboard interface. Now the problem is I can't click-expand the menus on the sidebar nor toggle the sidebar menu. And the main page is not extended to fill the space, as in our current application.
I know the function init_start() takes care of the resize and the click, which is already added to vendor.js from custom.js but I can't seem to call the function from ember at all.
My latest attempt was using mixins but it failed too:
import Ember from 'ember';
export default Ember.Mixin.create({
activate: function() {
this._super();
init_sidebar();
}
});
then from dashboard.js route:
import HandleTempLoadMixin from '../mixins/handle-temp-load';
export default Route.extend(AuthenticatedRouteMixin,HandleTempLoadMixin, {
});
but still the function is not executed.
I have read that it is best to avoid working with jquery inside ember in SO but I have pretty much many JQuery functions that I cant transfer right now (nor sure why exactly since it says somewhere in the documentation jquery is built into ember itself).
Anyway, what is the best way to initailize the dashboard interface?
From my understanding you have some jQuery stuff that you would like to utilise. I suggest looking into Component's didInsertElement hook and triggering your custom code from there.
You can find more details in here https://guides.emberjs.com/v2.17.0/components/the-component-lifecycle/#toc_integrating-with-third-party-libraries-with-code-didinsertelement-code
In general, try avoid working with view related stuff in Routes. Ember's power comes from strong conventions. Learning where to place your code is crucial.

Component to be notified on route change in EmberJS 2

My task is to develop a menu component for an Ember 2 app. This is going to be a complex component whose visual representation changes as the user goes through routes. For instance it should disable particular menu and all its items when on "/index" route but enable it and some of its items when on "/details" and so on.
So, I've got a component that is passed a singleton model (stored in a Service currently, btw, is it a right place to store globally available singleton models in Ember?). It displays the stuff well but it does not respect the current route nor catches the route changes as user goes through the app. How can I achieve it?
Summing it up:
The component needs to get current route somehow to be able to display its initial state, for instance the user bookmarked the "/details" page and visited it.
The component has to deal with route changes somehow.
Is a Service a good place to hold a singleton model (which could potentially be fetched from server).
Can you provide your thoughts on how to tackle the three above?
SOLVED: Ok, here's how it is done, thanks to #Bek's suggestions:
import Ember from "ember";
export default Ember.Component.extend({
router: Ember.inject.service("-routing"),
didInsertElement: function() {
let r = this.get("router");
console.log("Initial route", r.get("currentRouteName"));
r.addObserver("currentRouteName", this, "currentRouteNameChanged");
},
"currentRouteNameChanged": function(router, propertyName) {
console.log(router.get("currentRouteName"));
}
});
MORE QUESTIONS :) - I had to surround the currentRouteNameChanged function name with quotes (to make it a string) otherwise it was not called. I assume I miss something very basic and obvious here?
One more issue is the funky service name -routing - #Bek, any hints on how could I figure it out myself, is there a list of injectable stuff I could look up information in? It is not yet in Ember documentation I assume but where in the source code of it to check it out? How stable -routing name in general, would it become *routing or something in final version?
Answer to 1 and 2:
In latest versions of ember 2.x (in 2.2 at least) router is available as service so you can inject it to component router: Ember.inject.service('-routing') and observe changes on currentRouteName, but it is currently private service so should be used with caution as it might change (might be renamed to routing), there is also rfc https://github.com/emberjs/rfcs/pull/38 which proposes routable components which will be part of ember in the future.
Anser to 3:
Services usually stateless, but there can be exceptions and services made to share global logic/objects so it is not a bad idea

Ember JS: Can I make my UI state persistent?

I have off canvas navigation on the left and right of my ember application.
The state is controlled by a couple simple properties triggered by actions.
Template:
<a {{action 'leftToggle'}} class="left-blade">Debtor List</a>
<a {{action 'rightToggle'}} class="right-blade">Acivity</a>
Controller:
export default Ember.Controller.extend({
isLeft: false,
isRight: false,
actions: {
leftToggle: function() {
this.toggleProperty('isLeft');
},
rightToggle: function() {
this.toggleProperty('isRight');
}
}
});
I would like these properties to persist across page reloads, or if a user navigates away and then comes back to the page.
I am not sure whether to store the properties in a model? or use localStorage, or what? It would seem like using a model just to store a simple thing like that is overkill, or if there is a better way? I am still learning ember, so I would like to learn a good habit.
This is mostly out of the scope of Ember.
Persisting data happens in a few places, localStorage, sessionStorage, cookie, url, or some sort of record persisted server side and fetched/updated client side.
This is really a pick your poison, you could attempt to use the Ember's new query-params feature and tack the state onto the url, which would involve Ember the most, but isn't necessarily the best option. Local storage seems just as easy to me.

Ember Data and Northwind OData

Could Ember-Data b3+ be used for work against a service like this, http://services.odata.org/V2/Northwind/Northwind.svc. If so, could anyone provide an example on how to use it to read OData.
For example a JSBin showing a list of customers where a customer list item can navigate to the orders of a clicked customer
I think this would be a great boon for developers working against different data protocols to wrap their heads around how to wire up an Ember application with Ember-Data.
I've done this with fixtures but just couldn't really wire it up with actual server data.
Edit
Since I wrote this, I have abandoned Ember and fell back to angular for my SPA data apps. The main reason behind this is Ember Set which you should use for Ember to wire up all its binding internals.
Unfortunately, this is not compatible with most libs like Jaydata or Breeze. At least not when you wish to make changes/saves to your entity service.
Jaydata and Breeze both use a propertyChanged property to monitor changes to your entity and Ember will prevent these changes with a You should use Ember Set error.
I could probably have written some sort of adapter to overcome this problem but really I didn't have time and I use a library "Ember" to make my life easier... not to have headaches on basics such as Data Service Queries.
So... I really love Ember, but unfortunately as long as they dont enhance "Ember Data" or drastically change the Ember Set policy, I can't use it!
Basically, if you plan to use a data library (JayData, Breeze) to update a backend...
DON'T USE EMBER!
Original
I had a look (very quickly!) at ember-data and wasnt thrilled really! It looks promising for Standard REST service which IMHO is not WCF's case.
I ended up using JayData for that purpose and I must say it integrates very well with Ember.
here is a quick snippet to get you going:
//Instanciate the Ember APP
App = Ember.Application.create();
//Tell the APP to initialize but to wait before launching
App.deferReadiness();
//Setup your JayData Store
//Entities.EntityModel was generated by JaySvcUtil
App.myStore = new Entities.EntityModel({
name: 'oData',
oDataServiceHost: <YOUR_WCF_ENDPOINT_URL>
});
//Create your route and populate model data
App.IndexRoute = Ember.Route.extend({
model: function () {
//This passes the toArray() promise to the model
return App.myStore.People.orderBy('it.Name').toArray();
}
});
//When JayData Store is ready, Fire the App
App.myStore.onReady(function () {
App.advanceReadiness();
});
Ember Route Model actually handles the promise given by JayData which allows us to just pass the query. see: http://emberjs.com/guides/routing/asynchronous-routing/#toc_the-router-pauses-for-promises

Cant figure out views rendering (they are prepended right before /body)

First my apologies: Im very new to ember.js and struggling so far.
I have a pretty basic app written and I've been using this as my main guide: http://trek.github.com/
My biggest issue right now is figuring out how to deal with Views, specifically the rendered HTML and where it appears in the DOM. It appears, at least with my app currently, the DOM elements are created and inserted into the page but right before /body. So everything just loads below the footer of my main site design.
Doesnt seem to matter where placement of the script templates are in relation to the page, or anything like that??
Is there a way to render views to an existing container div or something? Am I thinking about this wrong? Im used to working with jsRender where I have templates setup, but they typically rendered to an in-memory string that I then needed to insert into an existing container like $('#containerDiv').html(myRenderedHtmlFromATemplate);
Thanks for any help or guidance with this!
Ember will want its views to be hierarchical in the DOM so it can rely on event propagation. You probably noticed a <div class="ember-application"> that gets injected, and then all of your views are rendered inside of that.
You can specify the rootElement when you create your Application. The application will be created inside that element and leave the rest of the DOM untouched. If you don't specify that rootElement, then Ember will insert itself right before </body> as you observed.
Example:
window.MyApp = Ember.Application.create({
rootElement: "#containerDiv"
});
Without seeing code it isn't completely clear what exactly is going on, but, I do not see you mention anything about outlets so I assume that might be your problem.
Check out this url on outlets: http://emberjs.com/guides/outlets/
tuxedo25 has the best solution. If you are using StateManager you can also use the following:
App.StateManager = Ember.StateManager.create({
rootElement: '.content',
initialState: 'initial',
initial: Ember.ViewState.create({
route: 'initial',
view: Ember.View.create({ templateName: 'initial' })
})
});