ui.router including partials inside head - angularjs

I have the following template loaded with PHP:
<!DOCTYPE>
<html>
<head>
<div ui-view="head"></div>
<title>Main page</title>
</head>
<body>
<div ui-view="body"></div>
<div ui-view="scripts"></div>
</body>
</html>
I now want to define head, body, and scripts partials individually for each route. I did this, but I can't insert a view to the div inside the head element - it's not valid, and it doesn't work anyways.
How can I do this?
$stateProvider
.state('list', {
url: '/fooBar/list',
views: {
'body': {
templateUrl: 'list.html',
controller: 'ListCtrl'
},
'head': {
templateUrl: 'head.html'
}
}
});

Related

Angular UI Router - using ui-sref on child view to change parent view

Im fairly new to angular UI. I am trying to have a ui-view that has a child a tag that has an sref that will change its parent ui-view
Something like this:
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div ng-app="app">
<h1>Hello</h1>
<ul>
<li>
<a ui-sref="organisations">Click 1</a>
</li>
</ul>
<div ui-view="testview"></div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js"></script>
<script>
angular
.module('app', ['ui.router'])
.config(setViewStates)
;
function setViewStates($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
// Organisations
.state('organisations', {
url: '/',
views: {
'testview': {
template: '<p>view 1</p><a ui-sref="organisations.club">Click</a>',
},
}
})
.state('organisations.club', {
url: '/club',
views: {
'testview#': {
template: '<p>view 2</p>',
controller: function($scope) {
console.log('hello');
}
},
}
});
;
}
</script>
</html>
This is a small mockup of what I'm intending to do but ultimately, all I want to do is have a template with a table of items, and once you press on one of those items, the table template would be replaced with the details of that item, along with its state and url.
So the hierarchy is something like:
/club/list
/club/:clubId
.state('organisations', {
url: '/:id',
views: {
'testview': {
template: '<p>view 1</p><a ui-sref="organisations({id : id_of_this_file})">Click</a>',
},
}
})
if you have only one state with params as id, you can send id as new or any other keyword for the first time and manipulate the html with ng-if on whether you receive id as 'new' or the file id. if you receive new in id parameter show the table else if you receive proper id show the file data.

Multiple ng-app sharing ng-view and $route

I have an MVC application with Header and Content using Angularjs.
I have defined an ng-app in Content and load the content pages using $routeProvider. This is working fine.
I have a link in Header from where I want to show a page in Content area - this is outside of the ng-app. How can I do this without setting ng-app at the top ? Also suggest if there is some other way to accomplish the same, as many Master page websites are built around this UI design only.
Below is my code showing Master.cshtml and app.js. Let me know incase I need to provide some more code -
Master.cshtml -
#inherits WebViewPage
<!DOCTYPE html>
<html xmlns:ng="http://angularjs.org">
<head>
<title>#ViewBag.PageTitle</title>
<script src="~/Scripts/jquery-1.11.1.min.js"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/angularjs/app.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<li><a ng-href="#/headerLinkPage1">View cart</a></li>
</div>
</div>
</nav>
<div class="container-fluid" ng-app="rootApp">
<div ng-view></div>
</div>
</body>
</html>
app.js -
var serviceBaseAddress = 'http://localhost/MyWebApi/api/';
var rootApp = angular.module('rootApp', ['ngRoute', 'contentPage1', 'headerLinkPage1'])
.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/contentPage1', {
templateUrl: '../ContentPage1/Index'
}).
when('/headerLinkPage1', {
templateUrl: '../HeaderLinkPage1/Index'
}).
otherwise({
redirectTo: '/contentPage1'
});
}]);
If I understand you question correctly, you want modularity in your angular routes, you can use ui router to achieve this, I basically created a main app called app and then two sub apps called app1 and app2, try http://plnkr.co/edit/sk5EmMWQgcIfYlOteWtt , Let me know if thats not what you are looking for
(function() {
angular.module('app1', [])
.config(function($stateProvider) {
$stateProvider
.state('app1', {
url: '/app1',
abstract: true,
template: '<div ui-view="app1View"></div>'
})
.state('app1.child1', {
url: '/child1',
views: {
'app1View' : {
template: '<div>child 1, app 1</div>'
}
}
})
})
})();
(function() {
angular.module('app2', [])
.config(function($stateProvider) {
$stateProvider
.state('app2', {
url: '/app2',
abstract: true,
template: '<div ui-view="app2View"></div>'
})
.state('app2.child1', {
url: '/child1',
views: {
'app2View' : {
template: '<div>child 1, app 2</div>'
}
}
})
})
})();
So this way your sub modules app1 and app2 are completely independent of each other and you can add or remove more sub modules or sub routes within each of these sub modules

Can not render a child view outside the of the parent`s parent view with ui router

I have created a plunker repro here: http://plnkr.co/edit/zU3PtJamS61Ac0bAKToD?p=preview
When you go to the projects tab and click the Edit button I would expect that the Edit.Html view is rendered in the ui-view "outer".
When I debug then even the ProjectsEditController is created but the state is not really activated and the ui sticks to the projects view.
What do I wrong?
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<script src="app.js"></script>
<script src="AdministrationController.js"></script>
<script src="ProjectsController.js"></script>
<script src="ProjectsEditController.js"></script>
<script src="SettingsController.js"></script>
</head>
<body ng-app="routedTabs" >
<div class="wrapper">
<div ui-view="outer">
<header class="aside">thats the header </header>
<div ui-view="menu" id="menu" class="aside">this is the menu aside</div>
<div ui-view="content" class="main container">
<h1>Working on it... </h1>
</div>
</div>
</div>
</body>
</html>
Edit.html
<div ng-bind="title"></div>
<button ui-sref="main.projects.edit({id: 10})" class="btn btn-default primary">Edit</button>
app.js
var app = angular.module("routedTabs", ["ui.router", "ui.bootstrap"]);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("");
$stateProvider
.state("main", {
abtract: true,
url: "",
views: {
'content#': {
templateUrl: 'administration.html',
controller: 'AdministrationController'
}
}
})
.state("main.projects", {
url: "/projects",
views: {
'menu#': {
template: 'test'
},
'planner#main': {
templateUrl: 'projects.html',
controller: 'ProjectsController'
}
}
}).state('main.projects.edit', {
url: '/edit/:id',
views: {
'outer#': {
templateUrl: 'edit.html',
controller: 'ProjectsEditController'
}
}
})
.state("main.tab2", {
url: "/settings",
views: {
'menu#': {
template: 'bla'
},
'planner#main': {
templateUrl: 'settings.html',
controller: 'SettingsController'
}
}
});
});
UPDATE
According to #Karthik`s statement I can not render the edit view into the "outer" ui-view.
I have prepared here a plunker without abstract main state and tabs. In this sample is just a projects view with an edit project button which should render the edit view into the ui-view called "outer" and indeeded it works!
http://plnkr.co/edit/ogQIpfHz7Cy9Jo03czKL?p=preview
So my new question is, what is the difference between those samples that it works in this plunker but not in the tabs plunker?
And how can I concretely make it work with tabs then?
Your projects is working and edit tab is displayed (if you debug your js code you will see it). In your case problem is in your AdministrationController.js.
On every update event form tabset is called go function with route /projects (current tab)
$scope.go = function(route){
$state.go(route);
};
This changes state back to main.projects so it seems like state was not changes which it actually was.
You probably want to re-write triggering within AdministrationController.js or found out why is update/go function triggered when leaving tab.
See if answer in this topic helps. You could use this approach instead of update function.
As temporary solution could be used something like:
$scope.go = function(route){
if($state.$current.name != 'main.projects.edit'){
$state.go(route);
}
}

ui-router global state param

I am using ui-router for my router. I want to implement i18n and for it I've created the following states
$stateProvider
.state('main', { url: '/:lng', abstract: true, template: '<div ui-view></div>'})
.state('main.index', { url: '/', templateUrl: '/views/index.html'})
.state('main.gallery', { url: '/gallery', templateUrl: '/views/gallery.html', controller: 'GalleryCtrl'})
And created the following links
a(ui-sref='main.index') Home
a(ui-sref='main.gallery') Gallery
However this links look like:
for index //
for gallery //gallery
I have found out that in uiSref directive he cannot inherit params from abstact main state.
Am I doing wrong with states?
Upadate:
I have one problem. I binded params to the scope object. In the ui-sref directive there is a watcher that tracks the params change, but in the handler of the watcher there is the following checking
if (newVal !== params) update(newVal);
However, when I try to debug the params is changing to the new param (I actually don't understand how, because params is assigned only once) and in the if check newVal === params
params = $scope.$eval(attr.params) //something like this
I even tried to use Object.observe on param object but it doesnot trigger before "watch" handler is triggered.
Now, I changed if check to make my code work.
There's nothing wrong with your state definitions from what I gather, but you're not passing any parameters to your ui-sref? Your state main.index & main.gallery still expect you to give it.
Working plunkr: http://plnkr.co/edit/uaII8LkMKoAHnacrLybQ?p=preview (Launch it seperate window to see url changes)
HTML:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#*" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular.js"></script>
<script data-require="ui-router#*" data-semver="0.2.8" src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
</body>
<a ui-sref='main.index({lng:5})'>Home</a> <br/>
<a ui-sref='main.gallery({lng:5})'>Gallery</a>
</html>
JS:
// Code goes here
angular.module("app", ["ui.router"]).config(["$stateProvider",
function($stateProvider) {
$stateProvider
.state('main', {
url: '/:lng',
abstract: true,
template: '<div ui-view></div>'
})
.state('main.index', {
url: '/',
template: '<span>Index</span>'
})
.state('main.gallery', {
url: '/gallery',
template: '<span>Gallery</span>',
})
}
]);

AngularJS - nesting of partials and templates doesn't work

I'm trying to implement the solution offered by ProLoser in link
in my Plunk. My problem is that whenever I press a link instead of opening in a sub-view below the links it overrides the entire view.
I need to understand how to solve this problem.
My flow is like that: index.html -> content.html (ng-view) -> link1/2/3.html (using ng-include).
My layout:
Index.html:
<!DOCTYPE html>
<html ng-app="webApp">
<head>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<script src="app.js"></script>
</head>
<body>
<header>This is header</Header>
<div class="content" ng-view>
</div>
</body>
</html>
content.html:
<div>
<h1>This is Content brought to you by ngView</h1>
<br>
link1
link 2
link 3
<ng-include src="'/sub/'+link + '.html' "></ng-include>
</div>
My code:
var webApp = angular.module('webApp', []);
//router logic
webApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'content.html',
controller: 'MainCtrl'
})
.when('/sub/:link', {
controller: 'LinkCtrl'
})
.otherwise({redirectTo: '/'});
}]);
//controllers
webApp.controller ('MainCtrl', function ($scope, $routeParams) {
$scope.link = $routeParams.link
});
You don't have a LinkCtrl to handle the links, it should work if you change:
.when('/sub/:link', {
controller: 'LinkCtrl'
})
to
.when('/sub/:link', {
templateUrl: 'content.html',
controller: 'MainCtrl'
})
And edit the line:
<ng-include src="'/sub/'+link + '.html' "></ng-include>
to:
<ng-include src="link + '.html'"></ng-include>

Resources