Question

I'm creating a multi-step wizard using angularjs. The steps in the wizard could potentially change by actions the user takes. I'm storing the steps in a navigation service. I want the navigation controller to respond to changes in the navigation steps (which occurs in the service). How do I do this? The below code does not work. Also I am using ui-router for the wizard steps, I'm wondering if I'm going about this the wrong way and the steps should be stored in the parent $scope rather than in a service. But examples I've found online suggest using a service.

Here's a jsfiddle I wrote to exhibit the behavior (http://jsfiddle.net/uLytj/16/)

Wizard Navigation Service:

angular.module("myApp").factory("wizardNavigationSvc", [function () {
    var service = {};
    var steps = []
    var currentStep = {};
    var currentStepIndex = 0;

    return {
        init: function() {
            steps = [{ state: "wizard.options", display: "Options", isActive: true, isFirstStep: true },
                     { state: "wizard.newmodel", icon: "glyphicon-plus", otherActions: ["Add Another Model"] },
                     { state: "wizard.other", display: "Other" },
                     { state: "wizard.customer", display: "Customer Info" },
                     { state: "wizard.shipping", display: "Shipping Info" },
                     { state: "wizard.review", display: "Review", isLastStep: true }];
            currentStep = steps[0];
            currentStepIndex = 0;
        },
        steps: steps,
        currentStep: currentStep
    };
}])

Wizard Navigation Controller:

myApp.controller('wizardNavigationCtrl', ['wizardNavigationSvc', '$scope', '$state', function (wizardNavigationSvc, $scope, $state) {
    wizardNavigationSvc.init();
    $scope.steps = wizardNavigationSvc.steps;
    $scope.currentStep = wizardNavigationSvc.currentStep;
}])

Wizard Navigation view:

<div>
    <ul class="nav nav-tabs wizard-tabs">
        <li ng-repeat="step in steps"
            ng-class="step.isActive ? 'active': ''">
            <a ui-sref="{{step.state}}">
            <span ng-if="step.icon" class="glyphicon" ng-class="step.icon"></span>
            <span ng-if="!step.icon">{{step.display}}</span></a>
        </li>
    </ul>
</div>
Was it helpful?

Solution 2

I do not understand why this worked or was needed. I had to put my scope variables inside the service within another object. Here is the fiddle: http://jsfiddle.net/uLytj/25/ And here is the applicable code:

myApp.service("wizardNavigationSvc", [function () {
    var navigation = {
        steps: [],
        currentStep: {},
        currentStepIndex: 0
    };

OTHER TIPS

looking at your jsfiddle, its not defined because the service is not returning anything

Ex: on one of the lines (in your service) you have:

steps: steps,
currentStep: currentStep,

these should be:

steps: function(){return steps),
currentStep: function(){return currentStep},
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top