EmberJS multiple controllers on one page - javascript

Is it possible to have multiple controllers on one route / page. I want to show 2 features of my application on one page. But they are not directly related so each would need it's own controller, model and (partial) view.
But I can't seem to figure out how I could do this.
It seems that I must use the {{render}} option here.
Is it possible to have a subdirectory structure here?
When I have {{render "dashboard.users"}} for the template it does look in template/dashboard/users.hbs but for the controller I can't seem to find where it looks and what the naming conventions should be.
E.g. should it be
App.DashboardUsersController = ... ?
edit:
Looks like it should be, but I shouldn't place it in a subfolder of controllers but name it dashboard_users_controller.js

You get this effect by rendering templates into multiple outlets of their parent template: Guide and API Docs
Here is a running JSBin demonstrating it

Related

How to structure app with Angular JS

I am trying to learn Angular JS and use it in my web app project and am looking for some guidance as well as answers to specific angular js questions. Tech stack I am using is MySQL db, Java w/ Spring Framework, HTML/CSS/Bootstrap/JS, etc..
The purpose of the app is basically a "social media craigslist" where it will have:
1. User accounts
2. Ability to create a "newsfeed-esque" post (one "view")
3. Ability to create a sale post (separate "view")
4. A view for an "inventory"
5. A view for a "wishlist"
etc..
(note: Items 2-5 are accessed via a nav bar of sorts that sits on the left side of my page and the idea was to have the main section of the page switch the content based on what nav item you clicked.. more later..)
What I was doing was writing a bunch of Javscript code to make calls to my web services (grabbing static content to populate drop downs, sending user login info for logging in, etc..) and the < script > tags were growing and all of this was living in my index.html page and I thought it might make more sense to use something like Angular JS and structure it a bit differently and "modularize" the code so it wasn't a giant mess in index page. I was also doing some manual .hide() and .show() JS stuff so I thought that it also might make more sense to switch out the content using something like AngularJS instead of having maximum ONE .show() active at once and then having to do as many .hide()'s as I would need to, to manually switch out the content. This is sounding like a SPA (single page app) right?
I have researched AngularJS StackOverflow posts and looked at w3schools and other helpful websites but am having trouble with how to structure this and use best practices not only with code efforts but organizational as well.
1) Am I correct in thinking Angular would make the hide and show of content easier?
2) I would like to make each "feature" of my website have its own controller and have Controller1.js, Controller2.js, etc.. but do I need to have a
var app = angular.module('myApp', []); ...
line at the top of each controller or do I need something like a main controller with that in there only once and then a call to each controller from a main controller? Or is this not even how I should go about it? Thought process was again to modularize and avoid having one giant beastly file with all my JS logic in it.
3) I assume that I need to use the ng-route stuff (is this correct?) in order to do that hide and show of html content? (items 2-5 listed above) But in what file should that live? a javascript controller file? index.html? other?
4) I read you can only have one ng-view per application. Does that mean that you can only switch/change the content for ONE < div > / section of your web app, OR can you have multiple different divs being changed?
5) fyi - my current file structure is pretty much this.. is this how it should be?
-Java Resources (java code)
...
-WebContent
-img
-META-INF
-resources
-css (folder)
-js (folder with js files - controllers)
-WEB-INF
-lib (folder)
-views (folder)
-xx-servlet.xml
-web.xml
-index.html
-pom.xml
A lot of my questions are just because I am new to AngularJS and not seasoned in JS itself so am trying to better understand. Thanks for any and all help in advance.
First of all, if you want to use multiple views per app then you should use angular-ui-router module instead of angular-route module.
Now, we come to the file handling. So, for that you can make as much file as you can to define controllers, config, services and factories for the app. There are three ways of doing this.
The first one is putting var app = angular.module("MyApp",[]); in first file and defining controllers and services like app.controller('ctrl', ControllerFunction) in each of the other files below the first one. But, personally i don't prefer to use this way as you are exposing your app as a global variable here.
The second way is to create a main module in first file using angular.module('MyApp',[]) and in other files you can get it and define controllers using angular.module('MyApp').controller('ctrl', ControllerFunction). This is the safer way than the previous one.
The third way is to create a different module in each of the files and using all the modules in a single main module as dependencies. Like below
in one file
angular.module('Module1',[]).controller('ctrl1',CtrlFun1);
in another file
angular.module('Module2',[]).controller('ctrl2',CtrlFun2);
and in the main file, the main module, which is to be bootstraped
angular.module('MyApp',['Module1','Module2'])
This is the safest way to define services in different files. I personally advise this way of using multiple js files in single app. Because here you care not exposing a global variable or a single module, so anyone cannot inject some code using console easily.

Get all available Templates in Ember

I'm trying to get all available templates in Ember, as of 2.16.x Ember.TEMPLATES doesn't seem to work anymore. Basically I need exactly this, is there an alternative?
I'm trying to dynamically load a route's template based on a model property. I already have the logic working, all I need is a list of the templates.
Related, but doesn't work anymore: List all available Handlebar Templates in the JavaScript console
Thanks!
You can access all of the entries via window.requirejs.entries. If all your templates are fitting some naming or directory rules then you can find the list of them. For example, if all of your templates resides under templates directory, you can find them as following:
var getKeys = (Object.keys || Ember.keys);
getKeys(window.requirejs.entries).forEach(itemName=>{
if(itemName.indexOf('templates')>=0){
console.log(itemName, itemName.indexOf('templates')>=0);
console.log(window.requirejs.entries[itemName]);
}
});

Controllers in AngularJS and templates

I'm fairly new to AngularJS and I want to have the best practices from start. I want to know where should I put which controller I'll be using for a specific template. For now I've used this two:
In the html of the template
<div ng-controller="ImageManagerController"> </div>
In my routes.js
.state('home',{
url : '/',
templateUrl : '/src/images/views/home.html',
controller : 'ImageManagerController'
})
Is one of them better than the other?
Thanks for your time!
When you do both you will create 2 instances of the controller, you don't want that
The biggest advantage of setting it in the routing config is that any related resolve will be made available for injection in the controller that is referenced.
Also when you have a lot of routes it is easy to look up which controller you would need to modify for any specific route when they are all listed in a config
Using ng-controller directive in HTML :
This scopes the controller to a specific element on the page/template. That can make the code easier to read when you need multiple controllers on a single page and it allows the controller to be more specifically scoped.
New $scope object will created on ng-controller.
visible with page source or inspect element.
Controller in Route :
Allows you to specify a single controller for a template. Since this is part of the routing it makes it easy to find the controller that goes with the page. I use this to store and load overall page logic rather than element specific logic.
New $scope object is created per route on the ng-view.
Not visible with page source or inspect element.
If you will use this <div ng-view ng-controller="ImageManagerController"> then you'd need to change that controller as the route changed. So basically the router does that for you, and uses the controller you specified when you defined your routes.
I hope these differences will help you in deciding which to use.

second level ember route not rendering

I've been having a good deal of trouble recently trying to get sub templates to render in Ember. The jsbin below doesn't work because I'm trying to use the REST adapter and just can't figure it out how to get mockjax and ember working together -- anyway, I think the REST adapter critical to the problem, as I will explain.
So I have a contact item. I can see ember calling my /api/contacts route to grab the model for all the contacts for listing. After this, I'm trying to create a link to an individual contact and have that render within the same template. In other words, I would still see the list of contacts, but I also see information on the individual contact that I just clicked on. That individual contact contains many contactPoints. Basically, what's happening is that I never see ember looking for the contactPoints. I see the "contact" template render, but it never has any contactPoints.
If this unclear, I can clarify. But the link below should help. Thanks!
http://emberjs.jsbin.com/xacuyalu/6/edit
I've simplified a bit your JsBin to highlight the solution
http://emberjs.jsbin.com/xacuyalu/7
With what you are trying to achieve, there's no need to name outlets.
The main problem in your code is the way you use variables inside loops and templates.
In your contacts template, you write
{{#each contact}}
But then forget to use contact as a variable when passing values
The same way, in your contact template, you use contactItem that doesn't exist. You can simply use the attribute of your model here.
The problem with mockajax was the url you were mocking /api/contacts instead of /contacts. This works in my modified JsBin.
Also please note that your payload won't work with contactPoints
EDIT: I've updated the JsBin to display the contact points.
http://emberjs.jsbin.com/xacuyalu/9
First thing, I would recommend you to read this https://github.com/emberjs/data/blob/master/TRANSITION.md. It will show you how to prepare your data to work nicely with Ember Data.
I have extracted your payload to be more readable. Here are the things that I've done:
Sideload contact points
Change the name of the attribute in the json from contactPointsIds
to contactPoints
add the address attribute on the ContactPoint model
Rename the attribute on the Contact model from contactPoint to
contactPoints

Multiple Layers of Deep Linking in AngularJS

I am attempting to place multiple controllers within my template partials with AngularJS- The problem I am encountering is that of the first layer, direct-linking to these sub-controllers and their related snippets.
An example would be a management page for user accounts, say I am on a user-list and wanted to change a user from the list's password, I click on their change-password button, and want to redirect the user to #/ManageUsers/ChangePassword/?UserID=<uid here> rather than #/ManageUsers_ChangePassword/ or similar, but the Angular documentation (Or lack thereof) on the subject suggests that this is impossible, or not 'The Angular Way'...
Being that my team wants to keep these separate controllers as partials, is there a non-hacky way to do this with Angular?
There has been recently published a blog post about one possible way of solving deep linking with AngularJS. It has a parent/child style of implementation where parent sections do not need to be updated if you need to change only contents of the child, which makes it pretty neat.
It's here: http://www.bennadel.com/blog/2441-Nested-Views-Routing-And-Deep-Linking-With-AngularJS.htm
why not direct to #/ManageUsers/ChangePassword/:UserID ? You can get the UserID from $routeParams. See an example on the $route page.
You can even create routes like #/ManageUsers/:OrganizationID/:SectorId/:UserID/ChangePassword/Confirmation that will be used by the url #/ManageUsers/10/2/32/ChangePassword/Confirmation

Categories

Resources