ncuillery / angular-breadcrumb Goto Github PK
View Code? Open in Web Editor NEWGenerate a breadcrumb from ui-router's states
Home Page: http://ncuillery.github.io/angular-breadcrumb/
License: MIT License
Generate a breadcrumb from ui-router's states
Home Page: http://ncuillery.github.io/angular-breadcrumb/
License: MIT License
When I try to access an state
TypeError: Cannot set property '$$templates' of undefined
at BreadcrumbDirective (http://localhost:9098/scripts/core/utils/breadcrumbs.js:179:20)
at Object.invoke (http://localhost:9098/bower_components/angular/angular.js:3966:17)
at http://localhost:9098/bower_components/angular/angular.js:5690:43
at forEach (http://localhost:9098/bower_components/angular/angular.js:325:18)
at Object. (http://localhost:9098/bower_components/angular/angular.js:5688:13)
at Object.invoke (http://localhost:9098/bower_components/angular/angular.js:3966:17)
at http://localhost:9098/bower_components/angular/angular.js:3808:37
at Object.getService as get
at addDirective (http://localhost:9098/bower_components/angular/angular.js:6763:51)
at collectDirectives (http://localhost:9098/bower_components/angular/angular.js:6190:15)
why????
It would be nice if we could extend this to handle navigation through an infinite recursive state.
ex:
A
A-a
A-a-aa
A-a--aa-aaa
A-a-aa-aaa-aaaa
....
B
B-a
B-b
Where each node has children of type node - (Recursion)
In case 2 states (list & detail) are children of the same parent (for example in the ui-router sample:
contacts (abstract)
├-- contacts.list
└-- contacts.detail
A property is needed on contacts.detail state's configuration to tell the breadcrumb that its parent is the contacts.list
The breadcrumb must be:
contacts.list / contacts.detail
An abstract state must not be a step in the breadcrumb because it can't be accessed.
Our spa is not http://website/
but rather http://website/some/folder
The breadcrumb urls are not being generated with a hash
#
before:
e.g.
/home
instead of #/home
Obviously this would fail the navigation.
Is there a setting to tweak?
The breadcrumb would be perfect for automatically populating the page title (either from the last fragment, or all fragments joined together for small sites). Is that possible?
Hi,
I just started using angular-breadcrumb and have run into an issue where a child route doesn't have the correct URL. The relevant routes:
.state({
name: 'project-detail',
url: '/project/:projectId',
templateUrl: '/static/ng-app/partials/project-detail.html',
controller: 'ProjectDetailController',
data: {
ncyBreadcrumbLabel: '{{current_project.project_name}}',
ncyBreadcrumbParent: 'home'
}
}).state({
name: 'subject-group-list',
url: '/project/:projectId/subject-groups/',
templateUrl: '/static/ng-app/partials/subject-group-list.html',
controller: 'SubjectGroupController',
data: {
ncyBreadcrumbLabel: 'Subject Groups',
ncyBreadcrumbParent: 'project-detail'
}
})
When I go to the subject group list, the breadcrumb link back to the parent project looks like:
http://localhost:8000/#/project/
when I expected it to look like:
http://localhost:8000/#/project/1
I'm sure I'm missing something simple, but I've tried all kinds of variations and I'm at a loss as to what the problem may be.
Thanks in advance, and let me know if you need addition code.
The animation could probably have 2 steps:
$breadcrumb.getStatesChain() raise the error below when using ncyBreadcrumbSkip: true on the very first step
Example
.state('admin', {
url: '/admin',
templateUrl: 'views/layout.html',
data: {
ncyBreadcrumbLabel: 'Admin',
ncyBreadcrumbSkip: true
}
})
.state('admin.dashboard', {
url: '/dashboard',
templateUrl: 'views/dashboard.html',
controller: 'DashboardCtrl',
data: {
ncyBreadcrumbLabel: 'Dashboard'
}
})
TypeError: Cannot read property 'data' of null
at $$isInherited (http://127.0.0.1:9000/bower_components/angular-breadcrumb/dist/angular-breadcrumb.js:31:49)
at $$addStateInChain (http://127.0.0.1:9000/bower_components/angular-breadcrumb/dist/angular-breadcrumb.js:60:18)
at Object.getStatesChain (http://127.0.0.1:9000/bower_components/angular-breadcrumb/dist/angular-breadcrumb.js:124:21)
It will be very nice to expose this to the configuration.
Abstract states should not be clickable as same as current state.
Hi there - first of all thanks for the great tool! 👍
But - there seems to be a conflict with famous-angular.. when both are used angular-breadcrumb stops working.. i can't really figure out why, but i created a plnkr to demonstrate..
the error occurs, after navigating to the second view.. and then consistently.. i have no idea why ;)
maybe you have an idea ?
http://plnkr.co/edit/wClm2JUizgtSTpkgawvt
i'd be glad for any feedback!
see this Plunker: http://plnkr.co/edit/BN0M2vvZccDq1KOKsSfC
Btw: awesome module! :)
If I set my own template via $breadcrumbProvider.setOptions({ templateUrl: ... }) then steps are empty, as $rootScope.$on('$viewContentLoaded', function (event) { .. }) never triggered.
Thats the url: http://ncuillery.github.io/angular-breadcrumb/#/booking/2014-5-23
When I change the date to 2014-5-24 then it should change/reflect in the UI too, but it does not.
To say it in other words I would appreciate a 2-way-databinding of the state :-)
for example 'bootstrap3':
'<ol class="breadcrumb">' +
'<li ng-repeat="step in steps" ng-class="{active: $last}">' +
'<a ng-if="!$last" href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel}}</a> ' +
'<span ng-if="$last">{{step.ncyBreadcrumbLabel}}</span>' +
'</li>' +
'</ol>'
what do you think?
I'm using angular-breadcrumb with ui state router. I have anchor with ui-sref="app.page", which becomes href="/page", and it works perfectly, taking me to http://localhost/app/#/page. However, the breadcrumb for app.page only has href="/page", and it takes me to http://localhost/page, which 404s.
my state provider is
$stateProvider
.('root', {
'abstract': true,
'views': {...}
})
.('app', {
'abstract': true,
parent: 'root',
'views': {...},
ncyBreadcrumb: {
skip: true
}
.('app.home', {
url: '/',
views: {...}
ncyBreadcrumb: {
label: 'Home'.
parent: 'app'
}
})
.('app.page', {
url: '/page',
views: {...}
ncyBreadcrumb: {
label: 'Page'.
parent: 'app'
}
})
.('child', {
url: '/page/:childId',
views: {...}
ncyBreadcrumb: {
label: '{{child.name}}'.
parent: 'app.page'
}
})
When I'm on the child page, and click the breadcrumb for app.page (which has the same href as the main nav), I end up at the wrong URL. It looks like what UI Router takes as '/' is the root of the angular app ('http:/localhost/app/#/') but whereas breadcrumb interprets '/' as 'http:/localhost'. The latter is not even in my app.
Consider this example:
.state('mystate', {
url: '/url',
views: {
"@": {
templateUrl: 'tpl.html',
controller: function ( $scope, $state, $stateParams ) {
$scope.title = 'mytitle';
}
}
},
data: { ncyBreadcrumbLabel: {{title}} }
substitution doesn't work in such cases and I have no clue how to workaround this.
What is the reason to use href
and not ui-sref
within the templates? Leads to a page-reload for me.
Hi, would it be possible to use substitution when providing ncyBreadcrumbParent ?
The "parent" I want to provide has some obligatory url parameter.
I'd like it to have like this:
data: {
ncyBreadcrumbParent: 'projects({group: currentProject.groupId})',
ncyBreadcrumbLabel: 'Project {{ currentProject.name }}'
}
It should work exactly the same way as parent
Defining the state
...
.state('admin.application.detail', {
url: '/:id',
templateUrl: 'views/application/configuration.html',
controller: 'ConfigurationCtrl',
data: {
ncyBreadcrumbLabel: 'State {{foo}}'
}
});
And a controller
...
.controller('ConfigurationCtrl', function ($scope, ...) {
$scope.foo='bar';
...
The result is "State {{Foo}}"
When you have multiple ui-views
, the ncyBreadcrumb.parent
function gets executed for each of the views.
This is not correct, you should be able to specify for what view
/controller
/scope
to get the parent
and label
executed against.
How can you do that?
Seems that ncyBreadcrumbLink
isn't correct after upgrading. My template:
<ol class="breadcrumb">
<li ng-repeat="step in steps | limitTo:(steps.length-1)">
<a href="{{step.ncyBreadcrumbLink}}" ui-sref-opts="{ reload: true, inherit: true, notify: true }">{{ step.ncyBreadcrumbLabel }}</a>
</li>
<li ng-repeat="step in steps | limitTo:-1" class="active">
<span>{{ step.ncyBreadcrumbLabel }}</span>
</li>
</ol>
https://www.dropbox.com/s/yjuimrv8ch2hbio/Screenshot%202014-10-20%2011.53.52.png?dl=0
Some features and breaking changes need an update of the docs.
ncyBreadcrumb.parent
and global option prefixState
can be a functionncyBreadcrumb.parent
and global option prefixState
accept url paramsincludeAbstract
Looking at the datepicker I can not click some days because the buttons are disabled by some logic. When I change the url to some disabled dates I can activate these day-states although that should not be possible :-) Thanks for the fix again.
First of all, thanks a lot for this great plugin!!
I am using this with dynamic values and I encountered a possible issue. This might regard to #15 But I am not sure..
How it works now
I give the label a dynamic value, similar like the example below. When I go to a certain state (e.g. ui-sref='mystate'
) this is working and it shows the dynamic value it got from the controller as supposed to.
.state('mystate', {
url: '/url',
views: {
"@": {
templateUrl: 'tpl.html',
controller: function ( $scope, $state, $stateParams ) {
$scope.title = 'mytitle';
}
}
},
data: {
ncyBreadcrumbLabel: '{{title}}'
}
});
Problem
When I refresh the page or go to a direct url (e.g. somesite.com/url
) to get the state. The dynamic value isn't passed to the breadcrumb label. It seems like it is only working when you are using the states via ui-sref
or maybe others as well.. The value is still in the scope, but somehow the breadcrumb can't get to it and the value it once had is lost.
Possible solution
Make sure that the dynamic value is saved somewhere or it can get to the scope where the value was in so you can still use it and when you go to a state and there is a value available (e.g. !empty String) which is changed, then it should update the current value. As the states change, the scope also changes and it's possible that's the reason why it is looking in the current scope for the value. Using the $rootScope of Angular and an array of values which check with the current state where it is now. I will try to implement an example with the usage of $rootScope in the meanwhile.
Please add it to npm
as well (angular
is added to npm
too) so we can use it with browserify
and not needing to add bower
's overhead
Hi
What I want to do is to simplify the code of the directive and put all the logic into the directive.
Advantages are:
Some work to do:
I have worked on top of #23 so as soon as you merge it I will rebase my branch with your master and submit a pull request.
My code: c9d8ae4
More specific than #32
It is possible to add param to a parent ?
Let's say I have something like this :
.state('showArticle', {
ncyBreadcrumb: {
label: '{{ articleName }}',
parent: 'home'
},
url: '/article/:slug',
controller: 'articleCtrl',
templateUrl: 'article.html'
})
.state('editArticle', {
ncyBreadcrumb: {
label: 'Edit article {{ articleName }}',
parent: //Here I need to specify "showArticle" with a 'slug' param
//In this case, this fonction may generate the label of his parent
},
url: '/article/:slug/edit',
controller: 'articleEditCtrl',
templateUrl: 'articleEdit.html'
})
In order to end up with :
Home > An article > Edit
This is not an issue. Just wanted to know if I can dynamically populate the parent name in breadcrumb.
The app.js config is this,
.state('product.productdetails', {
url: '/productdetails',
views :{
"@product":{
templateUrl: 'views/productDetails.html',
controller: 'ProductDetailsCtrl',
}
},
data: {
ncyBreadcrumbParent: '{{breadcrumbParent}}',
ncyBreadcrumbLabel: 'Product Details'
}
})
This works for label but not with parent breadcrumb.
I got two use case,
Can this be done by making changes in ncyBreadcrumb directive, i saw u used $interpolate for label.
angular-breadcrumb It's possible use it with ng-route and $routeProvider ?
I am finding that breadcrumb labels bound to a controller's scope do not rebind on browser refresh.
Is it feasible to add the possibility of configuring a state to not show the breadcrumb when that state is active?
I have put the breadcrumb directive outside of the ui-view container, so as to not have to insert it in every view, but I do not want it to show up on when I'm in the home state.
Right now I solve it this way <div data-ncy-breadcrumb ng-hide="$state.includes('home')"></div>
, where I have added the $state
service to my main controller (or I could have used the root scope), but it would be really neat if I could avoid all this and configure it instead.
I was thinking of two possible ways this could be configured. Either as an array of names for states to exclude in the setOptions
method of the $breadcrumbProvider
:
$breadcrumbProvider.setOptions({
excludedStates: ['home', 'sitemap']
});
or by adding custom data to the state:
$stateProvider.state('home', {
url: '/',
templateUrl: 'home.html',
controller: 'homeController',
data: {
ncyBreadcrumbLabel: 'Home page',
ncyBreadcrumbExclude: true
}
});
I am opening this because I really don't know if it's possible or not. If it is, I think it is not documented. I have a state that can be reached from two different locations and I would like that the breadcrumb let's you go back to the location were you were at that moment.
Is this possible? I have been trying different stuff but could not make it yet.
Hi guys,
sorry for creating an issue if this turns out not to be one.
I have a project in which I load everything via requirejs, and I am not able to get the bindings to work (perhaps I am using it the wrong way).
Here is a stripped down version of the project, both views display the breadcrumbs, but they do not seem to see the scope of either controller.
https://github.com/paulflo150/breadcrumbs1
Any thoughts?
Thanks,
Paul
This is somewhat related to #28 but not the same thing.
In my current project I need to display some abstract states in the breadcrumb as simple, non-linked labels.
I have this requirement because the abstract states in question are "page categories" of sorts and they provide necessary context.
To achieve this I modified your code so that:
state.data.ncyBreadcrumbIncludeAbstract
is trueng-switch="$last || !!step.abstract"
(add span
instead of a
)Sorry if this has already been asked, but was wondering how I can display an icon like what follows below:
ncyBreadcrumbLabel: '<i class=\"fa fa-home fa-fw\">Home page'
When I try the above, it just displays <i class=\"fa fa-home fa-fw\">Home page
in breadcrumb instead of an icon.
I'm trying to get nested dynamic states in my angular app. Here is what my states look like.
.state('root.ui', {
url: '/ui',
abstract: true
})
.state('root.ui.container', {
url: '/:containerName',
views: {
'container@': {
templateUrl: '/templates/front/ui/container.html',
controller: 'containerCtrl'
}
},
data: {
ncyBreadcrumbLabel: '{{container.name}}'
}
})
.state('root.ui.container.category', {
url: '/:categoryName',
views: {
'container@': {
templateUrl: '/templates/front/ui/category.html',
controller: 'categoryCtrl'
}
},
data: {
ncyBreadcrumbLabel: '{{category.name}}'
}
})
.state('root.ui.container.category.scenario', {
url: '/:scenarioName',
views: {
'container@': {
templateUrl: '/templates/front/ui/scenario.html',
controller: 'ScenarioCtrl'
},
'[email protected]': {
templateUrl: '/templates/front/ui/image.html',
controller: 'ImageCtrl'
}
},
data: {
ncyBreadcrumbLabel: '{{scenario.name}}'
}
})
});
At the moment container.name and category.name are being set in the controller by getting the state params and putting them into the scope.
However when i try to navigate directly to a scenario my breadcrumbs look like this:
Home / / /
When i inspect the HTML behind it, the URLs are correct however no matter what i do the labels don't display correctly. If i remove the labels from my configuration the state names are displayed correctly instead.
I have tried setting all the labels in all of the controllers without success.
What am i doing wrong? Any assistance is appreciated.
When I use a special letter like "í" or "õ" on a ncyBreadcrumbLabel a strange char appears on the breadcrumb.
.state("newsdetails",
{
url: "/newsdetails{id}",
templateUrl: "news/details/views/NewsDetailsView.html",
data: {
ncyBreadcrumbLabel: 'notícia',
ncyBreadcrumbParent: 'newslist'
}
})
thank you
Hi,
There is a bug with the function $viewContentLoaded in your directive. I have nested states which are calling the same controller, and the same view template html. In my controller, in terms of the childs states, I apply filters on my template results. So, the state change but not the breadcrumb.
In order to fix it, I have added a listener on $stateChangeSuccess.
$stateProvider.state('a.b', {
url: '/:category-:categoryId',
views: {
'@a': {
templateUrl: 'partials/layout.html',
controller: 'ABController'
},
'@a.b': {
templateUrl: 'partials/index.html',
controller: 'AControler'
}
},
data: {
ncyBreadcrumbLabel: 'Part_category'
}
});
$stateProvider.state('a.b.make', {
url: '/brand-:brandLabel-:brandId',
views: {
templateUrl: 'partials/index.html',
controller: 'ABController'
},
data: {
ncyBreadcrumbLabel: 'by_brand'
}
});
$stateProvider.state('a.b.make.model', {
url: '/:slugModelLabel-:modelId',
views: {
templateUrl: 'partials/index.html',
controller: 'ABController'
},
data: {
ncyBreadcrumbLabel: 'by_model'
}
});
=======
$rootScope.$on('$viewContentLoaded', function () {
renderBreadcrumb();
});
$rootScope.$on('$stateChangeSuccess', function () {
renderBreadcrumb();
});
I am not sure how ui-rooter works, but if the templateUrl not change, so the event $viewContentLoaded is not triggered ...
dir/1.txt
dir/dir2
dir/dir3/2.txt
...
like this ,use the same ui-sref
, how to use?
the exmple like this:
html:
<li ng-repeat="disk in disks" ng-switch on="disk.is_dir">
<a ui-sref="disks({path:disk.path})" ng-switch-when="true">{{disk.name}}</a>
</li>
js:
.state('disks', {
//breadcrumb: '???',
url: '/disks/{path:.*}',
templateUrl: 'disks.html',
})
I'm following your example:
$stateProvider.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: function($scope) {
$scope.foo='bar';
},
ncyBreadcrumb: {
label: 'State {{foo}}'
}
})
This works, but lets assume I don't have a controller assigned directly on state.
A view is loaded with it's own controller and service. The service gets data from a webservice, and only then, in the controller, the ncyBreadcrumb.babel can be updated. But I don't know how to reach it.
I added a simple expression:
.state("content",
{
url: "/content/:idMenu/:idSubMenu/:idContent",
templateUrl: "app/content/views/DynamicView.html",
ncyBreadcrumb: { label: "{{stateLabel}}" }
})
and in the controller assigned the stateLabel accessing the $rootScope
module.controller("ContentController", ["$scope", "$rootScope", "$stateParams", "LayoutService", "ContentService",
function ($scope, $rootScope, $stateParams, LayoutService, ContentService)
{
var itemContent = LayoutService.GetContent($stateParams.idContent);
ContentService.GetAsyncData(itemContent.json).then(function (result)
{
$scope.data = result;
$rootScope.stateLabel = result.title;
});
}]);
This works, but I don't know if is the best way or if the directive already was some magic behind it to easily achieve this. What is the best way to do this?
Thank you.
Hello,
I changed my ui-router config to have global state across my app (header/footer/sidebar), so now I have something like this:
// Home state routing
$stateProvider.
state('root', {
abstract: true,
url: '',
views: {
'header': {
templateUrl: 'modules/core/views/header.client.view.html',
}
},
data: {
ncyBreadcrumbSkip: true
}
}).
state('root.home', {
url: '/',
views: {
'content@': {
templateUrl: 'modules/core/views/home.client.view.html',
}
},
data: {
ncyBreadcrumbLabel: 'Dashboard'
}
});
The <div ncy-breadcrumb></div>
is on home.client.view.html.
I receive the following error:
Bad configuration : prefixState "home" unknown <ol class="breadcrumb ng-isolate-scope" ncy-breadcrumb="">
Any ideas?
Thanks
Hello,
Excellent plugin!
However, I cannot use the breadcrumb with routes that have parameters. When I click on a breadcrumb the route has no parameter in it. For example, what was before 'app/levels/1' simply becomes 'app/levels/'. How do I get the breadcrumb to keep the route parameters?
Let's say we have nested routes that are 3 levels deep, and the first 2 levels have 'ncyBreadcrumbSkip: true' :
$stateProvider
.state('contacts', {
url: '/contacts/',
template: '<div ncy-breadcrumb></div> <ui-view></ui-view>',
data: {
ncyBreadcrumbSkip: true
}
})
.state('contacts.list', {
url: 'list/',
template: '<div>List</div> <ui-view></ui-view>',
data: {
ncyBreadcrumbSkip: true
}
})
.state('contacts.list.detail', {
url: ':id/',
template: 'Detail',
data: {
ncyBreadcrumbLabel: 'Contact Detail'
}
});
The breadcrumbs will ignore 'ncyBreadcrumbSkip: true' for all except the topmost route.
The relevant code is in $$isInherited in $Breadcrumb:
return angular.isDefined(parentState) &&
angular.isDefined(parentState.data) &&
angular.isDefined(parentState.data[dataProperty]) &&
angular.equals(state.data[dataProperty], parentState.data[dataProperty]); // <-- here
If the state property value is ever the same as the parent's, it's assumed that it must have been inherited, when that's not always the case.
As a workaround I just ended up using another "truthy" value instead of true
in one of the middleroutes, i.e.
.state('contacts.list', {
url: 'list/',
template: '<div>List</div> <ui-view></ui-view>',
data: {
ncyBreadcrumbSkip: "truthyString"
}
})
I dont know if you can add a property to the directive to tell it which templates to not capture as a state and add to the chain.
When using nested view, ui.router will fire several $viewContentLoaded
.For instance if we have the following state:
resource
resource.list
resource.detail
If we access to detail directly, the last event fired will be for the abstract view. This mean that the binding of the breadcrumb is done on the abstract view's scope and not on the child view's scope.
I made a plunkr to demonstrate.
URL have multiple params with the same name:
?myarray=value1&myarray=value2
I try to pass mulitiple params to parent state:
ncyBreadcrumb: {
parent: function ($scope) {
var myarray = ['value1' , 'value2']
return 'main({myarray: ' + myarray + '})';
}
}
Unfortunately, it doesn't work.
Mail received from Luis Gonzalez
Hello,
I started using your angular-breadcrumb directive and it works great. After spending a couple of hours on google/stackoverflow and reading your docs I could not figure out how to hide the last breadcrumb.
So for example, in your sample app you have a page at http://ncuillery.github.io/angular-breadcrumb/#/room/1
where the breadcrumb trail is Home/Sample/Rooms/Room 101. But I don't want to display the last one in the array so I would like the breadcrumb to read Home/Sample/Rooms
Can you give me a suggestion about how to make this change, I tried adding to the state ncyBreacrumbSkip with expression testing for current state so that it skips only the last item but couldn't get it to work, any help would be appreciated.
Cheers,
Luis
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.