Nested views with dot notation - angularjs

can someone help me with this nested views in angular js.
I use this dot notation
$stateProvider
.state('contacts/:id', {
templateUrl: 'contacts.html',
controller: function($scope){
$scope.contacts = [{ name: 'Alice' }, { name: 'Bob' }];
}
})
.state('contacts/:id.list/:id', {
templateUrl: 'contacts.list.html'
});
function MainCtrl($state){
$state.transitionTo('contacts/:id.list/:id' );
}
In html I call state change also like this
<a ui-sref="contacts/{{value.id}}.list/{{value.id}}">get<\a>
But always I get
angular.js:12477 Error: Could not resolve 'contact/2.list/2' from state 'contact/:id'
Thnx
EDIT:
I make a change like #Maxim Shoustin answered. Now state changed, but in child navigation when I click on item, parent ui-view is full refreshed (child navigation and ui-view) not only child
now my state looks like this
.state('client', {
url: '/client/info/:itemID',
templateUrl: 'clientInfo.html',
controller: 'detailControllerClient as vm',
})
.state('client.detail', {
url: '/detail/:itemID',
templateUrl: 'itemInfoById.html',
controller: 'detailControllerClient as vm',
})
And html is here. (infoDisplay.html is parent view inside index.html. This ui-view in code bellow is child view (client.detail))
infoDisplay.html
<div class="new_nav col-lg-1 col-md-1 col-sm-2 col-xs-12">
<table class="table-hover">
<thead>
<tr>
<th>item ID</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key, value) in clientDetail">
<td><a ui-sref=".detail({'itemID': value.id})">{{value.id}}</a></td>
</tr>
</tbody>
</table>
</div>
<div ui-view></div>

<a ui-sref="contacts/{{value.id}}.list/{{value.id}}">get<\a>
You cannot use id.list with id because Angular determines like duplicated name id in pattern. But id_list is ok. For example
See ui-sref Docs
Where state is:
.state('contacts', {
url: '/contacts/:id_list/:id',
templateUrl: 'contacts.html'
})
and HTML:
<a ui-sref="contacts({'id_list': value.id, 'id': value.id})" >contacts</a>
Demo Plunker

Related

angularjs link between routes

I have set up a route as follows in my AngularJS app.
audit.config(["$routeProvider",function($routeProvider){
$routeProvider
.when('/AuditData/:auditCode', {
templateUrl: 'templ/AuditData.html',
controller: 'AuditDataController'
})
.when('/', {
templateUrl: 'templ/AuditSelect.html',
controller: 'AuditSelectController'
})
.when('/AuditSetup', {
templateUrl: 'templ/AuditSetup.html',
controller: 'AuditSetupController'
}}]);
The routing works as expected. The user is shown a list of audit codes in AuditSelect that are loaded from a REST service. Each item in the list is to be a link to the data associated with that code, i.e.: #/AuditData/:auditCode, <a href="#/AuditData/code123">.
(templ/AuditSelect.html):
<div>
<table>
<tr>
<th>Audit Code</th>
<th>Description</th>
</tr>
<tr ng-repeat="auditCode in auditCodes">
<td> {{auditCode.auditCode}}</td>
<td>{{auditCode.description}}</td>
</tr>
</table>
</div>
My problem is that when the users clicks on the link, they are taken back to '/' and not '/AuditData/:auditCode'.
Update:
I found what was wrong :-) I was missing a bang in the href in my template. I've also switched to using ng-href (which didn't work without the bang either, but does with it)
<td><a ng-href="#!/AuditData/{{auditCode.auditCode}}">{{auditCode.auditCode}}</a></td>

ng-app and ngRoute not working

I have the following script.js code
var app = angular
.module("Demo", ["ngRoute"])
.config(function ($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "Templates/home.html",
controller: "homeController"
})
.when("/courses", {
templateUrl: "Templates/courses.html",
controller: "coursesController"
})
.when("/students", {
templateUrl: "Templates/students.html",
controller: "studentsController"
})
})
.controller("homeController", function ($scope) {
$scope.message = "Home Page";
})
.controller("coursesController", function ($scope) {
$scope.courses = ["C#", "VB.NET", "ASP.NET", "SQL Server"];
})
.controller("studentsController", function ($scope, $http) {
$http.get("StudentService.asmx/GetAllStudents")
.then(function (response) {
$scope.students = response.data;
})
})
and the following is the html :
<body ng-app="Demo">
<table style="font-family: Arial">
<tr>
<td colspan="2" class="header">
<h1>
WebSite Header
</h1>
</td>
</tr>
<tr>
<td class="leftMenu">
Home
Courses
Students
</td>
<td class="mainContent">
<ng-view></ng-view>
</td>
</tr>
<tr>
<td colspan="2" class="footer">
<b>Website Footer</b>
</td>
</tr>
</table>
The routing does not work for the above href links. My partial pages consumes the properties of $Scope in the script.js file. But home.html never get loaded after clicking the link. Please help with why ng-app, ng-view, and ngRoute do not work for me.
Drop the hashes in your <a> tags.
it works now since I updated the code as following:
var app = angular.module('Demo', ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$locationProvider.hashPrefix('');//this helped fix a bug with angular 1.6.1 http://stackoverflow.com/questions/41211875/angularjs-1-6-0-latest-now-routes-not-working the routing links were not working but this $locationProvider variable change fixed it.
$routeProvider
.when('/home', {
templateUrl: 'Templates/home.html',
controller: 'homeController'
})
.when('/courses', {
templateUrl: 'Templates/courses.html',
controller: 'coursesController'
})
.when('/students', {
templateUrl: 'Templates/students.html',
controller: 'studentsController'
});
})

Module.filter not work in nested view

I have this code:
Var myApp = angular.module('myApp', ['ui.router', 'credit-cards']);
myApp.filter('yesNo', function () {
return function (boolean) {
return boolean ? 'Yes' : 'No';
}
});
myApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state("home", {
redirectTo: 'home.index',
url: "/home",
templateUrl: 'templates/home.html',
controller:'profileCtrl',
access: {restricted: true}
})
.state("home.index",{
url: "/inicio",
templateUrl: 'templates/index.html',
controller:'schedulerController',
access: {restricted: true}
})
.state("home.canchas",{
url: "/canchas",
templateUrl: 'templates/canchas.html',
access: {restricted: true}
})
.state("home.usuarios",{
url: "/usuarios",
templateUrl: 'templates/usuarios.html',
controller:'usuarioController',
access: {restricted: true}
})
.state("home.torneos",{
url: "/torneos",
templateUrl: 'templates/torneos.html',
access: {restricted: true}
})
$urlRouterProvider.otherwise("/home/inicio");
});
This is the template:
<Div class="container">
<form name="ccForm">
<div class="form-group">
<label for="card-number">Card Number</label>
<input type="text" class="form-control" id="cardNumber" cc- number cc-eager-type name="ccNumber" ng-model="card.number">
</div>
<table class="table">
<tr>
<th>Valid</th>
<th>Eager Type</th>
<th>Type</th>
</tr>
<tr>
<td>
{{ccForm.ccNumber.$valid | yesNo}}
</td>
<td>
{{ccForm.ccNumber.$ccEagerType || 'Unknown'}}
</td>
<td>
{{ccForm.ccNumber.$ccType || 'Unknown'}}
</td>
</tr>
</table>
</div>
And then I have the routes and states.
My problem is, if I use the filter in the principal index.html, the filter works ok, but when I put the html code in other nested view, the code does not work!
Thank in advance!

UI-Router, I am trying to pass id in the url, but I keep getting nothing

I am trying pass id in the url so that it can be use by other page more specifically the detail page but i keep getting nothing. the url is going to the correct route but the id is not getting passed in. i have no idea what i'm doing wrong.
here my app.js file:
$stateProvider.state('contact', {
url: '/contact',
templateUrl: 'templates/contact.html',
controller: 'mainController'
});
$stateProvider.state('contact.detail', {
url: '/detail/:id',
templateUrl: 'templates/contact.detail.html',
controller: 'detailController'
});
and here is my controller file:
myApp.controller('detailController', ['$scope', '$stateParams',
function ($scope, $stateParams) {
'use strict';
$scope.peoples = $scope.peoples[$stateParams.id];
}]);
and here is my contact file:
<div class="container">
<div class="row">
<div class="col-md-6">
<table class="table table-striped">
<thead>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</thead>
<tbody>
<tr ng-repeat="person in peoples">
<td><a ui-sref="contact.detail({id: person.id})">{{person.firstname}}</a></td>
<td>{{person.lastname}}</td>
<td>{{person.age}}</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<div ui-view></div>
</div>
</div>
There is a working example
One thing is:
searching with indexer, e.g. $scope.peoples[someIdValue] will not find by ID but by position (index)
The second point would be:
do not re-assign a reference $scope.peoples with new value (and lose that reference)
So, this should be the fix (using lodash to find person)
.controller('detailController', ['$scope', '$stateParams',
function($scope, $stateParams) {
//$scope.peoples = $scope.peoples[$stateParams.id];
$scope.person = _.find($scope.peoples, {id: $stateParams.id});
}])
Check that all in action here

ui-sref not generating the href

I'm not sure what is the mistake I'm doing here but the href is not generating. I have configured as per ui-router example but when I put the ui-sref in the ng-repeat its not generating the URL and also when I type the URL manually also its not working.
Even when I tied to set the value like data-ng-click="widget.open({widgetId: 1}) nothing happens.
Here is my code snippet.
Config:
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
$stateProvider
.state('home', {
url: '/',
templateUrl: '/templates/home/home.html'
})
.state('widget', {
// With abstract set to true, that means this state can not be explicitly activated.
// It can only be implicitly activated by activating one of its children.
abstract: true,
// This abstract state will prepend '/widgets' onto the urls of all its children.
url: '/widget',
// Loading a template from a file. This is also a top level state,
// so this template file will be loaded and then inserted into the ui-view
// within index.html.
templateUrl: '/templates/widgets/index.html'
})
.state('widget.open', {
url: '/{widgetId:[\w+$]}', //matches [a-zA-Z_0-9]
templateUrl: '/templates/widgets/index.html'
})
.state('widget.create', {
url: '/{type:[a-zA-Z]}', // We can test enum list also
templateUrl: '/templates/widgets/index.html'
})
.state('mashup', {
// With abstract set to true, that means this state can not be explicitly activated.
// It can only be implicitly activated by activating one of its children.
abstract: true,
// This abstract state will prepend '/mashups' onto the urls of all its children.
url: '/mashup',
// Loading a template from a file. This is also a top level state,
// so this template file will be loaded and then inserted into the ui-view
// within index.html.
templateUrl: '/templates/mashups/index.html'
})
.state('mashup.open', {
url: '/{mashupId:[\w+$]}', //matches [a-zA-Z_0-9]
templateUrl: '/templates/mashups/index.html'
})
.state('mashup.create', {
url: '/{templateType:[a-zA-Z]}', // We can test enum list also
templateUrl: '/templates/mashups/index.html'
});
}])
Template:
<div class="panel panel-default widget-list">
<div class="panel-heading">
<h3 class="panel-title">My Widgets ({{widgets.length}})</h3>
</div>
<div class="panel-body hp-content">
<table class="table table-condensed table-bordered">
<tbody>
<tr data-ng-repeat="w in widgets">
<td class="hp-type">Icon</td>
<td>
<div class="row">
<div class="col-xs-12">
<a data-ui-sref="widget.open({widgetId: w.id })">{{::w.name}}</a>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
{{::w.sourceId}}
</div>
<div class="col-xs-12 col-md-6">
{{::w.communityId}}
</div>
</div>
</td>
<td class="hp-actions">{{::w.access}}</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-footer">Panel footer</div>
</div>
Could someone please point the mistake what I'm doing?
Thanks
There is no need to wrap the widget.id in curly braces:
data-ui-sref="widget.open({widgetId: {{widget.id}} })
Use:
data-ui-sref="widget.open({widgetId: widget.id })">
I think your problem is a naming issue. You are in a repeater that is widget in widgets, so when you do widget.open, I think its looking for a open function in the the widget object of the repeater and not the sub route 'widget.open'.

Resources