issue with ui-router not working in the angular app - angularjs

I am trying to get the URL router working for my app but for some reason it will not link the files.
I have created a simple plnkr to demonstrate the issue ...
can someone please assist
http://plnkr.co/edit/XQs2vP4vtqnBWGKqmJZz
Thanks

There are some misunderstandings:
You did not specify a ui-view to render to state into
You configured the states as named views, which makes only sense if you need more than one ui-view in parallel (nesting views is always possible)
How to fix it
Use <div ui-view></div> in your views for normal views and use <div ui-view="content"></div> for named views (content is a custom name which you may choose at will).
Also, you can use the ui-sref attribute to link to specific states which is better practice than setting the href manually. In all demos below i showed both ways.
Note that normal views have a simpler state definition syntax:
.state('person', {
url: '/persons',
templateUrl: 'list1.html',
controller: 'employeeCtrl'
})
Demos
Demo with normal views (for single views)
Demo with named views (for multi-views)
In both cases you can nest views as a further exploration of the possibilites of ui-router (which makes it way superior to default angular routing):
Demo with normal views and nesting
Demo with named views and nesting
Unlimited possibilities.

Related

Load view/controller programmatically

How do I, at runtime, load a view / controller?
Say for example I have a list of content like so
ctrl.pages = [{
controller:"myController",
templateUrl : "/app/view.html"
},{
controller:"myController2",
templateUrl : "/app/view2.html"
}]
How do I then load those views and controllers? Is it simply just a case of using "ng-include" or is there a better way? Libraries such as Angular Material dont seem to do it this way.
<ng-include ng-repeat="page in ctrl.pages"
ng-controller="{{page.controller}}"
src="{{page.templateUrl }}"></ng-include>
That seems like either a case for a template expanding directive, see the Angular docs here. Or if those pages represent different "states" of the application, somewhere a user might visit directly via a URL, they'd be a good candidate for ui-router.
check this plnk out.
I added a select of available views and based on the selection ng-include's src is updated.
I avoided initializing the controller(s) intentionally, you may include them.

AngularJS setting the same ngapp more than once

The problem I am having is I need the root element as an anchor tag, then need a div under the anchor tag. They will both be using the same angular controller which belongs to the same app. The databind on vm.Open works find inside the anchor tag, but it is not working inside the div tag. How can I have the div tag also bootstrap as 'app' with the controller 'ordercontrol'?
Right now I have :
My HTML
<a data-ng-app="app" data-ng-controller="ordercontrol as vm" href="#" data-ng-click="vm.Open = !vm.Open">{{vm.Open}}</a>
<div data-ng-app="app" data-ng-controller="ordercontrol as vm" id="QuickOrderDiv">
<div class="row">
{{vm.Open}} //showing as '{{vm.Open}}' inside page
</div>
</div>
Per AngularJS documentation, only one application can be bootstrapped per HTML document. There is probably not a good reason for you to try and declare and use multiple apps in one document. Depending on your intention, there are a few ways to proceed.
First, remember: assigning a controller to an element (using the ng-controller directive) creates a new scope that inherits from the parent. All elements, directives, and additional controllers used within that scope can use that controller to share functionality. So in essence, a controller is used to centralize models and application logic that is specific to an application and usually to a view (think of any functional task in your application, such as an order form or log in page; those are serviced by controllers).
If you want to reuse a behavior multiple times throughout your application, and that behavior is not specific to a particular view in your application (think of a component, like a date picker, or perhaps a shopping cart status icon/link) you may wish to encapsulate your logic in a directive.
Now, there is some overlap (for example, directives can have a scope or controller of their own), and it may be confusing when to use one or the other. As I mentioned above, controllers are primarily intended to contain business logic for a view in your application. Directives are more orthogonal, encapsulated templates and logic that a) you can easily reuse across the views in your application, and b) extend existing HTML elements with richer mark-up and programmed behaviors. You can use a service (which is a single-instance object) to coordinate data between controllers and directives.
Another common issue new developers struggle with is maintaining or inheriting different states independently, considering that you can only have one ng-view element per document. In that case, consider ui-router.
My wild guess for your case, you may want some sort of QuickOrder directive that binds to a value on OrderController to determine whether or not it should display, and contains additional template mark-up for displaying the order or whatever and the logic to manage it.

Angular 1.2 - ui-router and accessing the parameter outside the controller

I'm using UI-Router to mange my routing on my application.
One item I've hit a snag on it with my menu which is the main view that the controllers will use.
for example I have a home link that should be
index.htm#/home/3
index.htm#/settings/3
3 is the companyId
but it seems that I can't access it that way. Does anyone have a suggestion as to how I could make that work?
Parent states should not be accessing the parameters of child states, but there is a little bit of magic that ui-router provides that might help. This is ui-sref-active. This directive will add css classes to html elements that have a ui-sref directive and that state is currently active. I think this would be sufficient to solve the problem that you have.

How can I programmatically/dynamically change the view?

I'd like to have a "wizard" of sorts where the screen changes a few times during the process. I'd like to utiilze Angular's controllers for this. I can't however, figure out how to change the view that's being displayed programmatically.
It doesn't look like there's any kind of $scope.setView('/path/to/my/view.htm') I can define.
You are going to want to learn about ngView => http://code.angularjs.org/1.1.4/docs/api/ng.directive:ngView
This way you can use $route to configure the display of partial content. You will want to declare the template option like:
$routeProvider.when('/path', {
templateUrl: '/path/to/my/view.htm',
}
Another option is to use ngSwitch => http://code.angularjs.org/1.1.4/docs/api/ng.directive:ngSwitch
For a wizard I would think that ngSwitch is less efficient but will be the easier of the two. This does sound like what you are looking for though.
"The ngSwitch directive is used to conditionally swap DOM structure on your template based on a scope expression."
document.location.href='#/yourRoute' to change the route programmatically
And if you want to use several views with 1 controller: define different routes with different views but the same controller

Router and refresh multiples ng-inludes

I start with code:
when('/admin', {
templateUrl: 'partials/admin/layout.html',
controller: AdminCtrl
})
when('/admin/products', {
templateUrl: '????',
controller: AdminProductsCtrl
})
Template "tree":
index.html ---> <div ng-view/>
---layout.html ---> <div ng-include=menu/> and <div ng-include=body/>
------menu.html
------products.html
Actually I do this:
function AdminCtrl($scope) {
$scope.menu = 'partials/admin/menu.html';
}
function AdminProductsCtrl($scope) {
$scope.menu = 'partials/admin/menu.html';
$scope.body = 'partials/admin/products/index.html';
}
The point is: What I put in '????', if I put layout.html this work fine, but I like just "refresh" ng-include=body. I think that my concepts about Angularjs is wrong.
Other problem is, when AdminProductsCtrl "take the control" of layout.html I miss the AdminCtrl $scope, this implicates repeat all AdminCtrl $scope in AdminProductsCtrl $scope (for example $scope.menu).
Thanks a lot, and sorry for "my english".
UPDATE
After think.. and think... I understanding that routes not apply for my app, then I manage all functionality under one url 'site.com/#/admin'. The menu.html is manage for AdminMenuCtrl, this controller contains a model for each 'ng-include' and contains one method for each menu entry. When the user click a menu entry, the associate method in the $scope replace $scope.includes.body with the 'new' html. The partial cointains your ng-controller.
This works fine by now :D. And the best is that I don't need use $rootScope.
The new problem is a bit more complicated, the ng-include require a tag (i.e DIV) and ng-controller too. Then my design is affected for this. In code language:
DESING:
<div>MENU-HTML</div>
<div>BODY-HTML</div>
TEMPLATE:
<div ng-include="menu"></div>
<div ng-include="body"></div>
AFTER RETRIEVE PARTIALS:
<div ng-include="menu"><div ng-controller="MenuCtrl">MENU-HTML</div></div>
<div ng-include="body"><div ng-controller="ListProductsCtrl">BODY-HTML</div></div>
THE IDEAL THING:
1 - ng-include don't 'include' into the DIV, instead 'replace' the DIV.
2 - ng-controller DIV is replaced for nothing in the DOM.
It's possible now with angular? Is a bad approach this idea? The point 2 with $route is possible, not with ng-controller directive.
I believe you are correct in your example you would set ???? to layout.html but the idea is to have different views based on the route so pointing to the same layout.html is not ideal.
If you are trying to keep a static menu on all pages I would add the menu to your index.html and then choose a different templateUrl for each route (ie /admin goes to partials/admin.html and /admin/products goes to partials/products.html) and not use the ngInclude.
I'm new to AngularJS but I'm getting the impression that you generally want to use ngView with routes to templateUrls OR use ngInclude (possibly with ngSwitch) if you want to roll your own view switching. I'm sure there are times when using both is appropriate but as a newbie it confuses me somewhat. Resident experts please correct me if I'm wrong!
For your second issue there might be some helpful information here and here for tips on sharing the same model across multiple controllers but you probably don't need to for your example.
An alternative is to use a string constant path to your partial in layout.html and remove the references to $scope.menu in your controller code by using:
<div ng-include="'partials/admin/menu.html'"/>

Resources