I am trying to implement ui-router(i.e $stateProvider) with my AngularApp.
My Logic is I have different modules. suppose Album (it have various views.)
What I am trying to implement is creating it as module. That means single controller for all states as well mixed logic in single controller file.
I created 1 files names list.
my state would be like this
.state('album', {url: '/album', templateUrl: 'views/album/list.html'})
//code would like this.
<li class="col-md-4" ng-repeat="item in items">
<p class="list-item">
<i class="fa fa-angle-double-right"></i>
<a class="cursor" href="#/poet/detail/{{item.id}}">{{item.name}}</a>
</p>
</li>
Now when we click it move to detail page. Having various tabs to render on same page. Corresponding states would be like this
.state('album.detail', {url: '/detail/:itemId', templateUrl: 'views/album/album.detail.html'})
.state('album.comment', {url: '/comment/:itemId', templateUrl: 'views/album/album.comment.html'})
.state('album.tracklist', {url: '/tracklist/:itemId', templateUrl: 'views/album/album.tracklist.html'})
.state('album.review', {url: '/review/:itemId', templateUrl: 'views/album/album.review.html'})
//All states have same controller, I would call services on switch condition on (states). Now issue is when I click on detail link from the list page I mentioned earlier it navigates to the base url.
//Instead of linking this http://0.0.0.0:3000/#/poets -> ttp://0.0.0.0:3000/#/poets/detail/12 It transfer to the base url i.e. - http://0.0.0.0:3000/#
Related
I am working on ionic framework. So I am confused with using ui-sref and href. For example for tabs we use ui-sref as we can have various states all linked to some main (base) url.
eg
.state('dashboard', {
url: "/dashboard",
templateUrl: 'templates/dashboard.html',
controller: 'dashboardCtrl'
})
.state('dashboard.active', {
url: '/active',
views: {
'active': {
templateUrl: 'templates/active.html',
controller: 'ActiveCtrl'
}
}
})
My dashboard page has tabs whish have various various states now if I want to move to a diffrent template from one of these states or templates (eg to active.html)
eg.
//active.html
<li class="item">
<a class="button button-positive" ui-sref="dashboard.editClaim"> Edit Claim
</a>
</li>
or
<li class="item">
<a class="button button-positive" href="#/dashboard/editClaim"> Edit Claim
</a>
</li>
here should i use ui-sref or href.
Also editclaim template has tabs should i use ui-sref there and will it work fine because currently that is the problem.
So I am wondering if I have to maintain some state till there. Thank you.
here should i use ui-sref or href.
From docs: https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
A directive that binds a link ( tag) to a state. If the state has
an associated URL, the directive will automatically generate & update
the href attribute via the $state.href() method. Clicking the link
will trigger a state transition with optional parameters. Also
middle-clicking, right-clicking, and ctrl-clicking on the link will be
handled natively by the browser.
<a ui-sref="home">Home</a> is converted to:
Home
Use ui-sref if you decided to use ui-router. This is a best practice. You can change in your code associated URL for the same state and you don't need to maintain your links.
Developers rarely use href for example in big lists for better performance to avoid additional watchers, but hope its not your case
<a class="button button-positive" ui-sref="dashboard.editClaim"> Edit Claim
</a>
is going to get convert in:
<a class="button button-positive" href="#/dashboard/editClaim"> Edit Claim
</a>
in your browser since ui-sref is just a simple directive provided by angular. For more info:
https://scotch.io/tutorials/3-simple-tips-for-using-ui-router
What's next? You should use ui-sref when using ui-router
I am trying to yield a piece of html into the navbar of a particular route in Angular 2. So this is not a part of the body component but is a part of the layout in the header of the page. How di i do this in angular 2?
This is what I did in AngularJS.
//header.html .. which is a partial within the layout
<div class="nav-wrapper">
<ul class="nav navbar-nav" ui-view="navbar_options">
<li>
<a href="" trigger-resize="" ng-click="app.layout.isCollapsed = !app.layout.isCollapsed" class="hidden-xs"> <em class="fa fa-navicon"></em>
</a>
<a href="" ng-click="app.asideToggled = !app.asideToggled" class="visible-xs sidebar-toggle"> <em class="fa fa-navicon"></em>
</a>
</li>
</ul>
</div>
//routes.config.js
.state('app.xyz', {
url: '/jobs/:jobID',
views:{
'': {title: 'abc',
templateUrl: helper.basepath('path/xyz.html'),
controller: 'myController',
},
'navbar_options': {title: 'my_page',
templateUrl: helper.basepath('path/xyz_navbar.html'),
controller: 'myController'}
}
})
I want to achieve the same in Angular 2
If I understand you correctly, you are trying to display a component in the navbar based on a certain route, but the main body of the page is also going to be updated on the route change. If I were you, I would use a "Secondary Route". I believe they are also referred to as "Named Routes"
Normally, your web page would be something like this:
<div class="app-content">
<router-outlet></router-outlet>
</div>
This works great if you are updating only one portion of your web page. If you want to update more than one portion, you need to provide several routes and they are named. They look like this:
<router-outlet name="myroute"></router-outlet>
I am guessing you will want one of these named routers in your navbar and then you have to create a link which places data in the named route... That link would look something like this:
<button md-button [routerLink]="['/mainroute', {outlets: {'myroute': ['routnamehere']}}]">
Open Two Routes
</button>
I'm trying to make a blog using AngularJS. The home page queries a third party service of mine that returns an array of all my articles/posts. I am displaying shortened versions of these posts on the home page, and want to have "read more" under each post that passes that post's ID through a URL parameter to another HTML page:
index.html:
<div ng-controller="blogCtrl" id="blog">
<div class="post" ng-repeat="post in posts">
<div class="header">
<h1>{{ post.fields.title }}</h1>
<p class="date">{{ post.sys.createdAt | date}}</p>
</div>
<p>{{ post.fields.body | cut:true:1600:' ...'}}</p>
read more
</div>
</div>
What do I need to do in post.html so that I can read the value of id in the URL parameter? Do I need to create a new angularJS app in post.html?
edit:
I've changed the read more link to <a href="post/{{post.sys.id}}"> and i am trying to set up the following route:
app.config(function($routeProvider){
$routeProvider
.when('/post/:postid',{
templateUrl: '/post.html',
controller: 'postCtrl'
})
});
However, clicking the "read more" link doesn't load up post.html, but instead a page that says File not found: /post/2B1K9K2DHqsYaGYcms2YeW. The route doesn't seem to be getting properly set up, since post.html isn't getting loaded.
This isn't all that hard to do, but you need to have routing set up on your app. You can create this functionality in your existing app, or separate it into a new one, it's up to you. Here are the relevant things you'll need to include in your code:
In your app include ngRoute as a dependency:
var myApp = angular.module('myApp', ['ngRoute']);
Also include routing config for your app:
myApp.config(function($routeProvider){
$routeProvider
.when('/someroute', {
templateUrl: 'someFolder/withSomeFile.html'
}
.when('/someroutewithparamters/:aftercolonisparameter', {
templateUrl: 'someFolder/post.html'
}
});
You can include a default route as well, but it's not necessary if you'd rather not. Be sure to include angular-route.js in your index.html for this to work.
Now in your controller you can simply do something like:
myApp.controller('postCtrl', function($routeParams, $scope, postFactory){
$scope.post = postFactory.functionToLoadPost($routeParams.aftercolonisparameter);
});
Obviously this will be different for your implementation based on how everything is set up, and you'll probably want to pick better names for your elements than I did, but those are the things you'll need in place to make this work. It's actually pretty straightforward.
So first off, I'm working on this for a project at work, but none of us have any idea how to do it, so it might be kind of vague.
Here is the template of how it is going to look: Template
So View A & B are going to have 3 states in them that will change the content of the view based on which one is selected
The problem I'm having is that only 1 view ever shows up and it is a test template for now because I don't have those views built but none of the sub views of View A ever show up.
HTML
<div id="main">
<div ui-view="viewa" class="col-sm-7">
<!--Content of ViewA supposed to be here-->
</div>
<div ui-view="viewb" class="col-sm-5">
<!--Content of ViewB supposed to be here-->
</div>
</div>
States:
$stateProvider.state("main", {
url: "/main",
views: {
"viewa#": {
abstract: true,
template: "<div ui-view></div>"
},
"viewb#": {
templateUrl: "btemps/default.html"
}
}
}).state("bobtheView", {
parent: "viewa",
//This is default for viewa
url: "/",
templateUrl: "atemps/bob.html",
controller: "bobController"
}).state("billtheview", {
parent: "viewa",
url: "/bill",
templateUrl: "atemps/bill.html",
controller: "billController"
}).state("joetheview", {
parent: "viewa",
url: "/joe",
templateUrl: "atemps/joe.html",
controller: "joeController"
});
//Supposed to route to viewa showing bobtheview and viewb showing the template
$urlRouterProvider.otherwise("/main/");
So when I go to the page and go to the root it redirects to the otherwise but nothing shows up, upon just going to main, only the viewb template shows up.
Any ideas? Any way I can format it better too? Is it better to go with "viewa.bobtheview" over having the parent attribute in the mix?
UPDATE: So I found a work around, I loaded each of the bobtheview, joetheview and billtheview in html partials, then I refactored it so the view state of viewa and viewb are controlled within a main template that includes the "ng-include" function to load the different templates, and since all of the data that is stored in those views is given via JSON rest requests, there is no change in the data bindings. The problem I'm facing now, is updating that "ng-include" on button click, I haven't done extensive research on it but I plan on doing so and I'll report back when/if I find something. If you have any ideas on this let me know! :D.
So I found a viable answer to the question at hand, after extensive research and asking around, I went with the option of having 1 Controller and configuration state
$stateProvider.state("main", {
url: "/",
controller: "mainController",
templateUrl: "temps/primary.html"
});
$urlRouterProvider.otherwise("/");
That went into the configuration settings, then my controller looked a little like this:
app.controller("mainController", ["$scope", "$state", "$stateParams", "$http", function($scope, $state, $stateParams, $http) {
$scope.viewatemp = $stateParams.at; //Numeric value to represent template url for viewa
$scope.viewbtemp = $stateParams.bt; //Numeric value to represent template url for viewb
//Do some other stuff here
});
Then the HTML of "temps/primary.html" looked a little something like this:
<div ui-view="viewa" class="col-sm-5" ng-include="viewatemp"></div>
<div ui-view="viewb" class="col-sm-7" ng-include="viewbtemp"></div>
I did a little manipulation of the numeric value of viewatemp and viewbtemp to get the actual URL, those are being loaded from a JSON request from my ASP.net WebApi 2 Restful service, but all in all, it is quick, rather simple and still gets the job done and allows for further enlargement of the project.
And that there in solved my problem, cool thing about this, I can have as many as these as I want because they are all separate states with nested "views"
If you do have a better answer, let me know! This is only what I found and what worked for me.
My question involves how to go about dealing with complex nesting of templates (also called partials) in an AngularJS application.
The best way to describe my situation is with an image I created:
As you can see this has the potential to be a fairly complex application with lots of nested models.
The application is single-page, so it loads an index.html that contains a div element in the DOM with the ng-view attribute.
For circle 1, You see that there is a Primary navigation that loads the appropriate templates into the ng-view. I'm doing this by passing $routeParams to the main app module. Here is an example of what's in my app:
angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when("/job/:jobId/zones/:zoneId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/zone_edit.html' }).
when("/job/:jobId/initial_inspection", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/initial_inspection.html' }).
when("/job/:jobId/zones/:zoneId/rooms/:roomId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/room_edit.html' })
}]);
In circle 2, the template that is loaded into the ng-view has an additional sub-navigation. This sub-nav then needs to load templates into the area below it - but since ng-view is already being used, I'm not sure how to go about doing this.
I know that I can include additional templates within the 1st template, but these templates are all going to be pretty complex. I would like to keep all the templates separate in order to make the application easier to update and not have a dependency on the parent template having to be loaded in order to access its children.
In circle 3, you can see things get even more complex. There is the potential that the sub-navigation templates will have a 2nd sub-navigation that will need to load its own templates as well into the area in circle 4
How does one go about structuring an AngularJS app to deal with such complex nesting of templates while keeping them all separate from one another?
UPDATE: Check out AngularUI's new project to address this problem
For subsections it's as easy as leveraging strings in ng-include:
<ul id="subNav">
<li><a ng-click="subPage='section1/subpage1.htm'">Sub Page 1</a></li>
<li><a ng-click="subPage='section1/subpage2.htm'">Sub Page 2</a></li>
<li><a ng-click="subPage='section1/subpage3.htm'">Sub Page 3</a></li>
</ul>
<ng-include src="subPage"></ng-include>
Or you can create an object in case you have links to sub pages all over the place:
$scope.pages = { page1: 'section1/subpage1.htm', ... };
<ul id="subNav">
<li><a ng-click="subPage='page1'">Sub Page 1</a></li>
<li><a ng-click="subPage='page2'">Sub Page 2</a></li>
<li><a ng-click="subPage='page3'">Sub Page 3</a></li>
</ul>
<ng-include src="pages[subPage]"></ng-include>
Or you can even use $routeParams
$routeProvider.when('/home', ...);
$routeProvider.when('/home/:tab', ...);
$scope.params = $routeParams;
<ul id="subNav">
<li>Sub Page 1</li>
<li>Sub Page 2</li>
<li>Sub Page 3</li>
</ul>
<ng-include src=" '/home/' + tab + '.html' "></ng-include>
You can also put an ng-controller at the top-most level of each partial
Well, since you can currently only have one ngView directive... I use nested directive controls. This allows you to set up templating and inherit (or isolate) scopes among them. Outside of that I use ng-switch or even just ng-show to choose which controls I'm displaying based on what's coming in from $routeParams.
EDIT Here's some example pseudo-code to give you an idea of what I'm talking about. With a nested sub navigation.
Here's the main app page
<!-- primary nav -->
Page 1
Page 2
Page 3
<!-- display the view -->
<div ng-view>
</div>
Directive for the sub navigation
app.directive('mySubNav', function(){
return {
restrict: 'E',
scope: {
current: '=current'
},
templateUrl: 'mySubNav.html',
controller: function($scope) {
}
};
});
template for the sub navigation
Sub Item 1
Sub Item 2
Sub Item 3
template for a main page (from primary nav)
<my-sub-nav current="sub"></my-sub-nav>
<ng-switch on="sub">
<div ng-switch-when="1">
<my-sub-area1></my-sub-area>
</div>
<div ng-switch-when="2">
<my-sub-area2></my-sub-area>
</div>
<div ng-switch-when="3">
<my-sub-area3></my-sub-area>
</div>
</ng-switch>
Controller for a main page. (from the primary nav)
app.controller('page1Ctrl', function($scope, $routeParams) {
$scope.sub = $routeParams.sub;
});
Directive for a Sub Area
app.directive('mySubArea1', function(){
return {
restrict: 'E',
templateUrl: 'mySubArea1.html',
controller: function($scope) {
//controller for your sub area.
}
};
});
You may checkout this library for the same purpose also:
http://angular-route-segment.com
It looks like what you are looking for, and it is much simpler to use than ui-router. From the demo site:
JS:
$routeSegmentProvider.
when('/section1', 's1.home').
when('/section1/:id', 's1.itemInfo.overview').
when('/section2', 's2').
segment('s1', {
templateUrl: 'templates/section1.html',
controller: MainCtrl}).
within().
segment('home', {
templateUrl: 'templates/section1/home.html'}).
segment('itemInfo', {
templateUrl: 'templates/section1/item.html',
controller: Section1ItemCtrl,
dependencies: ['id']}).
within().
segment('overview', {
templateUrl: 'templates/section1/item/overview.html'}).
Top-level HTML:
<ul>
<li ng-class="{active: $routeSegment.startsWith('s1')}">
Section 1
</li>
<li ng-class="{active: $routeSegment.startsWith('s2')}">
Section 2
</li>
</ul>
<div id="contents" app-view-segment="0"></div>
Nested HTML:
<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>
I too was struggling with nested views in Angular.
Once I got a hold of ui-router I knew I was never going back to angular default routing functionality.
Here is an example application that uses multiple levels of views nesting
app.config(function ($stateProvider, $urlRouterProvider,$httpProvider) {
// navigate to view1 view by default
$urlRouterProvider.otherwise("/view1");
$stateProvider
.state('view1', {
url: '/view1',
templateUrl: 'partials/view1.html',
controller: 'view1.MainController'
})
.state('view1.nestedViews', {
url: '/view1',
views: {
'childView1': { templateUrl: 'partials/view1.childView1.html' , controller: 'childView1Ctrl'},
'childView2': { templateUrl: 'partials/view1.childView2.html', controller: 'childView2Ctrl' },
'childView3': { templateUrl: 'partials/view1.childView3.html', controller: 'childView3Ctrl' }
}
})
.state('view2', {
url: '/view2',
})
.state('view3', {
url: '/view3',
})
.state('view4', {
url: '/view4',
});
});
As it can be seen there are 4 main views (view1,view2,view3,view4) and view1 has 3 child views.
You may use ng-include to avoid using nested ng-views.
http://docs.angularjs.org/api/ng/directive/ngInclude
http://plnkr.co/edit/ngdoc:example-example39#snapshot?p=preview
My index page I use ng-view. Then on my sub pages which I need to have nested frames. I use ng-include.
The demo shows a dropdown. I replaced mine with a link ng-click.
In the function I would put $scope.template = $scope.templates[0]; or $scope.template = $scope.templates[1];
$scope.clickToSomePage= function(){
$scope.template = $scope.templates[0];
};
Angular ui-router supports nested views. I haven't used it yet but looks very promising.
http://angular-ui.github.io/ui-router/