I have the following code that adds html to a variable. However, when it get's shown on the page, the link doesn't work.
What's the best way to get a ui-sref link to work when inserting it dynamically?
JAVASCRIPT
.controller('page', function($scope, $rootScope, $http, $state, $sce) {
$scope.message = $sce.trustAsHtml('A <a ui-sref="login">login</a> link');
})
HTML
<div ng-bind-html="message"></div>
There is a working plunker
I would say, that we can use combination of:
$state.href() (doc here) and
ng-href (doc here)
(but only in case, if the params passed are part of url)
This would be the result
<a ng-href="{{$state.href(myStateName, myParams)}}">
And now (in the plunker) we can change myStateName into parent, parent.child, home and it will change properly the generated href:
<input ng-model="myStateName" />
<input ng-model="myParams.param" />
Because these are states in plunker
$stateProvider
.state('home', {
url: "/home",
...
})
.state('parent', {
url: "/parent?param",
...
})
.state('parent.child', {
url: "/child",
...
Check it here
Related
I am trying to make a nested views, here is the plunker https://embed.plnkr.co/oRMnMW4QoWwhSkm9maHf/. The state changes but the template not changes.
Can anyone correct me what have I done wrong
Goto Link > Second Nested .
On Clicking the button , state changes successfully but the content is not injected. I want the link page content to be replaced by the second-nested content
Try to put abstract:true on the 'father' root like:
var routerApp = angular.module('routerApp', ['ui.router','ncy-angular-breadcrumb']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home/list');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
abstract: true,
templateUrl: './partial-home.html'
})
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: './partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('home.second', {
url: '/second',
templateUrl: './second.html',
});
});
routerApp.run(['$rootScope', '$state', function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function (event, toState) {
console.log("state Change")
});
}]);
but Remember .. if you put abstract: true .. the url is not a real one .. it's a prefix .. or as i call it .. a father of other routing ..so you can not call it in the .otherwise()
And in your link (and routing) of the second view .. just remove the .list ... so like this:
.state('home.second', { //<-- HERE .. REMOVE THE .list
url: '/second',
templateUrl: './second.html',
});
and in the link:
// AND HERE ..
<a ui-sref="home.second" class="btn btn-danger">Second Nested</a>
Answer is pretty simple - you are initializing 3rd level of nesting states but in ./partial-home-list.html you've didn't add ui-view directive.
Add <ui-view></ui-view> in ./partial-home-list.html and you will see that it works as you defined.
If you want to display home.list.second as separate page then define second state like this
.state('home.second', {
url: '/home/list/second',
templateUrl: 'second.html',
});
Remember to update ui-sref to home.second on button
--
Just to get nested breadcrumb I have not "nice" solution but will work.
-- Partial home list html
<div ng-if="state.current.name != 'home.list.second'">
<ul>
<li ng-repeat="dog in dogs">{{ dog }}</li>
</ul>
<div ncy-breadcrumb></div>
<a ui-sref="home.list.second" class="btn btn-danger">Second Nested</a>
</div>
<ui-view></ui-view>
App js
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope, $state) {
$scope.state = $state;
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('home.list.second', {
url: '/second',
templateUrl: 'second.html',
});
I have implemented UI-Router in my application but I'm having a problem with a nested route. My index.html page looks like;
<body>
<!-- Navigation code -->
<!-- Content from the template -->
<div ui-view></div>
<!-- Footer -->
<!-- Application Scripts -->
</body>
My Angular ui-route code is;
(function () {
'use strict';
var app = angular.module('rbApp', ['ngAnimate', 'ui.router', 'ui.bootstrap']);
app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("home", {
url: "/",
templateUrl: "/App/WebSite/home.html",
controller: "homeController as homeVm"
})
.state("programs", {
url: "/programs",
templateUrl: "/App/WebSite/programs.html",
controller: "programsController as programVm"
})
.state("programs.complete", {
url: "/complete",
templateUrl: "/App/WebSite/programsComplete.html"
})
.state("articles", {
url: "/articles",
templateUrl: "/App/WebSite/articles.html",
controller: "articleController as articleVm"
})
}]);
app.run(['$rootScope', function ($rootScope) {
$rootScope.$on('$locationChangeStart', function (event, newUrl, oldUrl) {
console.log('Location change: %s --> %s', oldUrl, newUrl);
});
}]);
})();
When I select the "programs" route the page is displayed correctly and the "app.run" code above updates the console log with;
Location change: http://localhost:50321/#/ --> http://localhost:50321/#/programs
On the programs page I have an image within an anchor tag as follows;
<div class="col-md-3 hidden-sm hidden-xs">
<a ui-sref="programs.complete"><img class="img-thumbnail img-responsive" src="/Images/Programs/Program01Small.jpg" /></a>
</div>
When the image is clicked the console log displays;
Location change: http://localhost:50321/#/programs --> http://localhost:50321/#/programs/complete
So it appears the routes are behaving as expected. The only problem is the "programsComplete.html" template is not displayed, the browser continues to display the "programs.html" template.
I have checked the console log but no errors are displayed and currently the "programsComplete.html" only contains a <h1> tag and text so I can confirm the template is being loaded.
Can anyone advise why this would not be loading the template?
It seems that the parent template programs.html is just missing for its child. Be sure that this tempalte programs.html contains unnamed view target
<div ui-view="">
Each child is inserted into its parent. In case we want child to replace parent, we have to use absolute name, and in this case target the index.html like this:
.state("programs.complete", {
url: "/complete",
views : {
'#' : {
templateUrl: "/App/WebSite/programsComplete.html"
}
}
})
while this naming convention could be weird: views : { '#' : ..., it is just absolute name:
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
so '#' means unnamed view in the unnamed state === root state
I am using angular-ui-router module of AngularJS and have the following ui-sref which when I hover over shows http://localhost:3000/u/bob#/123/pin/4567, but when I click on it, I get only http://localhost:3000/u/bob#/123/pin/ on the browser's URL address bar and get the parameter value 4567 lost.
HTML code (index.html):
<a ui-sref="users.maker">
<!-- stuff -->
</a>
JavaScript code:
.state('users', {
url: '/:foo',
views: {
'': {
templateUrl: '/partials/index.html',
controller: ['$rootScope', '$stateParams',
function($rootScope, $stateParams) {
//stuff
}]
}
}
})
.state('users.maker', {
url: '/pin/:bar',
templateUrl: '/partials/users.maker.html',
controller: ['$stateParams', '$scope', '$http',
function($stateParams, $scope, ) {
//stuff
}]
})
Could somebody help me with it?
Have you tried defining your ui-sref as following?
ui-sref="users.maker({ param })
Dynamic ui-sref do not work in ui-router. A function using $state.href() could be used to resolve this issue.
So <a ui-sref="users.maker({ foo: bar })">...</a> could be done by following:
HTML
<a href="{{goToState('users.maker', bar)}}">..<a>
Inside AngularJS Controller
$scope.goToState = function(state, param) {
return $state.href(state, {foo: param});
}
This is with angular-ui-router version 0.2.10.
For more:
https://github.com/angular-ui/ui-router/issues/395
Using Angular UI router, I have a route set up as follows
$stateProvider.state('edit', {
url: '/:file/:page',
...
}
if I change the route from /edit/file1/page1 to /edit/file1/page2, the view doesn't refresh. I'm calling $state.go, and I can easily redraw the page, but by not running this through the router things like the back button don't update the route.
Can someone advise how to update the route so the view is updated?
Thanks.
If I understand your intention here, it is to have your templateUrl be based on the :file and :page $stateParams.
Since you haven't shown how you are actually using $state.go, I put together an example that shows a few of the ways you can change between states with and without { reload: true }.
angular.module('exampleApp', ['ui.router'])
.config(function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/file1/page1');
$stateProvider
.state('edit', {
url: '/:file/:page',
controller: 'FilePageCtrl',
templateUrl: function($stateParams) {
return $stateParams.file + "-" + $stateParams.page + ".html";
}
});
})
.controller('FilePageCtrl', function($scope, $state) {});
Here are some example links that change the state (but will not re-run the controller and template if it's already the current state):
<a ui-sref="edit({ file: 'file1', page: 'page2' })">/file1/page2</a>
Is more or less the same as (whether inline with ng-click or within a controller):
<a href ng-click="$state.go('edit', { file: 'file1', page: 'page2' })">/file1/page2</a>
The following two will force the controller and templateUrl to run, regardless if the current state is the same:
<a ui-sref="edit({ file: 'file1', page: 'page2' })" ui-sref-opts="{ reload: true }">/file1/page2</a>
<a href ng-click="$state.go('edit', { file: 'file1', page: 'page2' }, { reload: true })">/file1/page2</a>
You can read more about using a dynamic templateUrl here: https://github.com/angular-ui/ui-router/wiki#templates
Here is a working example: http://plnkr.co/edit/JUgUB3I675Kh7kKkitgJ?p=preview
Though the states are changing successfully, I can't get the ui-view to update:
HTML
<a ui-sref="promo.foo">Foo state</a>
<a ui-sref="promo.bar">Bar state</a>
<div ui-view=""></div>
JavaScript
$urlRouterProvider.otherwise("/");
$stateProvider
.state('promo', {
url: "/",
abstract: true
})
.state('promo.foo', {
url: "promo/foo",
template: "'<h3>Foo</h3>'",
controller: function($scope) {
$scope.value = 'foo';
}
})
.state('promo.bar', {
url: "promo/bar",
template: "'<h3>Bar</h3>'",
controller: function($scope) {
$scope.value = 'bar';
}
})
Plnkr (with bootstrap styling)
I have also tried setting ui-view to equal specific states also; and to dynamically change its RHS from my $scope.
Since you're trying to create nested views, the home state should have a template with an ui-view-element in it.
Also you have both double and single quotes in the template
template: "'<h3>Foo</h3>'"
Is this Plunker what you had in mind?
Give your abstract state a template containing inside which your sub states will render ... eg http://scotch.io/tutorials/javascript/angular-routing-using-ui-router