I need create one huge page on AngularJS. And I'm thinking which architecture is better for this page? So, page has 3 blocks with a lot functionality, but the main is: left block has accounts, user can pick some account and this account should be shown on center block. Center block can be changed and result should be shown on the right block.
For html I created 3 views for each block and included them with ng-include. Also I want somehow divide controller for few files, because I didn't work with a lot of code in one file. And I see a few ways, how to do this.
1. Create controller for each view, and transfer data by broadcast, or save data on RootScope and use watchers.
2. Create parent controller and transfer data by him.
What do you think about this? Or maybe one big controller is the best solution for this? And what is the best way for transferring data through controllers? Thanks.
There are many approaches for your situation, I'll tell you what I think is best
First of all, you make an parent abstract state where you can do all your dirty work in it, wither it was getting data from server or otherwise, inject all the data you need to use in $scope and then go to the child state "where your big page is"
something like that :
.state('parent_state', {
url: '/home',
abstract: true,
templateUrl: 'whatever',
controller: 'yourCtrl as yourCtrl'
})
.state("parent_state.child",{
//Whatever you need here
})
when you go to your child state you will have all the data you need in $scope , so you can focus more on logic instead of wrapping data
from my opinion, a page should have only one controller, there is no point if giving a controller to every portion of your view, else you need to go with custom directives
So if you have one controller that rules them all, or one controller and multiple directives.
your call
Related
Say I have two views that share a controller. Both views use the ng-route service. If a scope variable is changed in one view and then you switch to the second view, how come the second view doesn't update?
Example: My controller has a variable that = "hello". I output this variable just fine in both views. In view one I have an onclick that updates the variable to say "Whatsup". That works fine, but after the event I switch views and the second view is outputting "hello" still. Is there a way to share these? If not, then what is a technique to share data?
I'd like you to know that AngularJS is designed for SINGLE PAGE APPLICATIONS (SPA) so this behavior is not supported by the framework.
Each view have a different scope even though they share the same controller. So updating a scope variable for one view won't update the other.
If you want this behavior, I suggest using $on to listen to events.
Also, on your code you have $scope.test = 'hi'; that is hard-coded on your controller with no conditions or whatsoever which is why it reflects on both of your views who share the same controller.
Best practice is to have one view per controller. As your site scales, it would get very hard to manage multiple templates/views with one controller.
A service is the way to share data between controllers.
For your example, you could have a activate functions that are called when each view is rendered that gets the updated variable from the service you inject. Your on lick function should save the variable to the service to make it available across controllers.
I need to load some data into my angular app the first time it is loaded. The data needs to come from the server.
My app currently consists of a number of directives on a single view in an accordion. The directives are forms whose criteria needs to be met before the user can progress to the next accordion group. The first accordion group needs to use the data from the server to display to the user, there is a dependency on the data for the view.
What is the best way to inject this data in the first instance?
I could move the initial data call into the first directive but it doesn't really feel like it is 'its' job. I could create another directive to handle this load but then I would need manage the load order of the directives. I have had a look at ng-init which works well until the server call is made, during this call the directives run before it completes.
Any of the above would work for me in theory but i'm not sure that they are the best approach. What would you suggest is the best approach?
Thanks
You should use a resolve in your state, so, both views and controllers are called when the resolution is done.
have a look at this link: http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx
You can decorate your directives with ng-if attribute and, as value, pass a scope property that will indicate data load ex.
i'm very confuse about how ember controller works.
I'm starting with ember and ember-cli now, and i would like to understand more about how controller works.
If i have an nested route called new, inside a events resource, i should i have:
models/event
routes/events/new
templates/events/new
What about controllers?? I just work one simple controller, or should i use controllers/events/new too?
There isn't any generator command that will create every resource for me? I need call one by one?
Thanks.
What about controllers?? I just work one simple controller, or should i use controllers/events/new too?
This mainly depends on what is your controller needs to do. If it's only the essential stuff the controller does anyways, Ember will create that controller under the hood for you and automatically bubble actions up to its parent controller.
No better place than Ember guides to read what a controller is used for:
The simplest definition is:
Controllers allow you to decorate your models with display logic.
This means that you basically use them as the main communication layer between your route and your template. Essentially, you model comes from your route, through your controller and into your template. Actions happening in the template go up to the controller and then to the route. Therefore, controller is essentially the middle layer where you user your model (and other data) to control what is shown to the user, control what a user can do, control where can they navigate etc.
However, be aware of the plan for the future:
Controllers are very much like components, so much so that in future versions of Ember, controllers will be replaced entirely with components. At the moment, components cannot be routed to, but when this changes, it will be recommended to replace all controllers with components.
This means, that right now, controller responsibility is limited to two things:
Maintaining application state based on the current route
Handling or bubbling user actions that pass through the controller layer when moving from a component to a route.
All actions triggered on a template are first looked up on the controller, if it is not handled or bubbled (by return true) in the controller, they are looked up on the route.
Therefore, controllers for your /events or events/new routes aren't necessary at all, only if you want to handle things happening on those routes right away (in a smaller scope) instead of allowing everything to bubble up to the ApplicationController.
There isn't any generator command that will create every resource for me? I need call one by one?
Yes. Since, if you don't specifically create a controller, Ember just generates one for you behind the scenes. You need to specify where you want to handle things yourself.
You should visit the link I gave above (or here it is again) to the Ember guides that have many more examples in much more detail.
I've created a BookService that is used for storing (add), getting (getAll) and removing (remove) books. Now I want to use this BookService inside my controller to publish some methods that I can later use in my view. My controller looks like the following:
app.controller('BookController', ['BookService', '$scope', function(BookService, $scope) {
$scope.addBook = function() { BookService.add(); }
$scope.getAllBooks = function() { BookService.getAll(); }
$scope.removeBook = function() { BookService.remove(); }
}]);
As you can see, the controller is just a proxy that forwards the method calls to the service. Is this in general bad practice? And is there a better way to solve that using Angular.js? Calling the service directly from the view without a controller seems, to me like a bigger problem.
Best Practice
From what I can see this is perfectly good practice, I'm assuming that you're using $scope here to bind these services to a button or something similar. The Idea of using a factory or a service is to create some well organised reusable code that you can then instantiate in your controller exactly like you have done.
Controllers can get quite complex so moving basic functionality to your service is the best thing to do. In your case you have a relatively simple controller so you may not see the benefit of coding in this way. But I assure you that as your code base grows you will be required to code like this just to keep things readable.
Note
Just as an extra note I've added a data process that you might take with an example of a database request
database > API > service/factory > controller > view
This would be the correct path to take when requesting something from a database.
What you have shown is not bad practice; it is in fact recommended that you abstract resource management logic (like adding, removing and finding resources of the same type) into a separate service, for organization and maintainability and reusability purposes.
I do understand from your example how the controller seems to be just a proxy to the service though, and why you would think it's repetitive and possibly redundant. Let me expand on your example to see if I can explain the reasons for abstracting the logic. In doing so, let's consider only the adding operation, even though the logic would apply to others as well.
Reason 1: adding a book (or any resource for that matter) in a web app is usually more complicated than just a bookService.add() call. It requires having some sort of form to enter the details, a submit button to handle the actual request, possible massaging of the entered data, adding new fields like time stamps and author ids, and persisting to some data storage. The first two or three of those steps would be applicable to the screen or view from which you are adding, so it makes sense to put that in a controller (the view model), whereas the rest of the steps should go into the generic service.
Now say you have another screen where you see a friend's list of books and you can add it to your list by selecting a book. In that case, the controller logic for that view's controller will differ from the previous example, but the service steps will still be identical, and thus do not need to be duplicated since the service can be injected into both controllers.
That's a big win.
Example 2: let's say you've already split the code between controller and service as describe in example 1 above. Then you decide that your data storage needs have changed and now you want to update your logic to save to a different database system. Now instead of having to change all the controllers, you just change your services and the everything works.
This is also a really big win.
Yes you'ved done this correctly. Just keep in mind that as you scaled up your app in complexity, you'll want to have isolated scopes, (and) decomposition into component directives. Each directive will have its own controller and template fragment.
I'm new to Ember, come from an Angular background. Let's say I have an number of elements, each of which holds a different data.
#elem1 10
#elem2 20
#elem3 30
I want to bind each of these elements individually to Ember models/controllers that hold the data. So something like:
script(type="text/x-handlebars", data-template-name="elem1").
{{data}}
App.Elem1Controller = Ember.ObjectController.extend({
data: 10
});
This should be really easy... but I'm having a hard time navigating through all the different naming conventions and routing/terminology of Ember. How can I go about doing this?
The first thing to determine is which route and controller is associated with your view and then wire up the components accordingly.
Here is a simple example in a JSBin.
This one uses a separate controller and route for the three properties. And they are rendered into the application outlet when the link is clicked.
If you need to use multiple controllers then you can include them in the controller that is associated with your view by using the "needs" dependency injection.
Here is another one that just uses the application template and associated controllers etc.
It also shows how you can include controllers in other controllers which might be more what you are looking for. It also shows you how to reference them in the template.