angular-bootstrap-tour
angular-bootstrap-tour copied to clipboard
Skip doesn't work in ng-repeat
Hi!
I'm trying to put a tour step on an item inside a ng-repeat, and just noticed the "skip" option doesn't work — I'm guessing because ng-repeat creates its own child scope. Using 0.3.2 btw.
Super weird — the steps
array isn't populating with any of the steps inside the repeater, but they're still appearing in the tour...
Interesting, I haven't tried to put a tour step on a ngRepeat. Can you paste the markup here so I can take a look?
Did you ever resolve this issue? I have the same scenario
so, after some head banging, I decided to use ng-if to choose if to render a div with or without the tour step. Here is my code..
<div class="col col-sm-6 col-md-4 col-lg-3 small-pad" ng-repeat="activity in activities" >
<div ng-if="$index === 0" class="panel panel-default nav-panel"
tour-step="" order="2" placement="top"
title="You next activity"
content="This is the next activity that needs to be started.">
...the rest of the panel with the tour step contents here
</div>
<div ng-if="$index > 0" class="panel panel-default nav-panel" >
...the rest of the panel without the tour step
</div>
</div>
I hope this helps someone...
@swrocket @benmarch Apologies for not checking back! I think I solved the issue by refactoring the ng-repeats I had so that the row with all the tour popovers was outside the ng-repeat. So, the issue's still there AFAIK.
No worries, this was an old post. Glad you found a solution
@swrocket did you use ngIf instead of skip? Did that result in the expected behavior or is it still buggy?
@benmarch I used ng-if. You can see my code above. My solution works, but it's a brute force hack really. I tried passing a hard value to skip (skip="{{$index>0}}") so that it's not trying to read a value from the scope, but that didn't work either.
@swrocket thank you for the additional info, I will look into it. My best guess is that it is related to the scope inheritance, and my next version of the plugin will use scope: false for tour steps to avoid these issues.
Looking forward to the next version :) Now to try to fake the tour to navigate to another state (ui-router) after the last step on a page.
@swrocket Thanks, that helped me big time, thought I was going crazy until I saw someone with the same problem.
@benmarch Could indeed be a scoping issue. I put some debugging logs in your code and stepIsSkipped()
is recognizing skipped steps in my ng-repeat, and summarily removing them from the array. Likewise the watcher immediately following that in the code is triggered for each element which is then added or removed:
skipWatch = scope.$watch(stepIsSkipped, function (skip)...
But this only happens on the first initialization. When restart() is called the stepIsSkipped() code is executed again, but I never see that skipWatch ever executed again.
@benmarch On a whim I tried changing your watcher code to use rootScope (and injected $rootScope into that directive):
skipWatch = $rootScope.$watch(stepIsSkipped, function (skip) {
Fixed the problem. Not sure if rootScope is the most elegant solution, I often feel like I'm cheating somehow when I use it, but it works. I'm not certain why this fixed it, as the watcher code still doesn't appear to be getting called additional times after restart().
@esoyke Thank you for the insight. I got side-tracked with the Angular UI version while fixing this issue, so this will give me a good place to start again.
@benmarch @esoyke — while I'm still subscribed to this issue, if you want a path around using $rootScope, maybe try the new controllerAs syntax? I found it helped with quite a lot of scoping issues in one of the larger apps I've been building.