独立于控制器的步进功能

时间:2016-09-20 12:04:55

标签: javascript angularjs angularjs-scope angular-services angular-controller

我有一个AngularJS项目,我正在使用md-steppers的修改版本,其有趣的功能归结为:

var enableNextStep = function () {
            //do not exceed into max step
            if ($scope.selectedStep >= $scope.maxStep) {
                return;
            }
            //do not increment $scope.stepProgress when submitting from previously completed step
            if ($scope.selectedStep === $scope.stepProgress - 1) {
                $scope.stepProgress = $scope.stepProgress + 1;
            }
        };

        var completeCurrentStep = function (CurrentStep) {
            $scope.stepData[CurrentStep].completed = true;
        };

        $scope.moveToNextStep = function moveToNextStep() {
            if ($scope.selectedStep < $scope.maxStep) {
                enableNextStep();
                $scope.selectedStep = $scope.selectedStep + 1;
                completeCurrentStep($scope.selectedStep - 1); //Complete After changing Step
            }
        };

        $scope.moveToPreviousStep = function moveToPreviousStep() {
            if ($scope.selectedStep > 0) {
                $scope.selectedStep = $scope.selectedStep - 1;
            }
        };

问题是我想在两个不同的控制器中使用这四个函数(以便不重复它们),它们具有不同的stepProgressselectedStepmaxStep值。我找不到使用服务的方法,但我可能只是对AngularJS的工作方式感到困惑,因为我更习惯于Python。

感谢。

2 个答案:

答案 0 :(得分:0)

将该功能抽象到接受回调数组和控制器ng-model的工厂中会使其更具可重用性。当然,最终您想要的API取决于您。目标是您不希望工厂内有任何$scope业务,它不应该关注回调中的内容,只是逐步完成它们。

/**
 * @param steps {array} - array of callbacks
 */

function stepperFactory(steps) {
  iterate(0, steps);
}

function iterate(current, steps) {
  if (!steps[current])
    return;
  if (typeof steps[current] === 'function')
    // pass an async "done" callback
    // so your array of input callbacks can be async
    // you could also use promises or $q for this
    steps[current](() => iterate(current + 1, steps));
}

所以你揭露的api就像:

['stepperFactory', function(stepperFactory) {
  this.model = { step: 0, msg: 'start' };
  this.steps = [
    (done) => {
      this.model.step++;
      done();
    },
    (done) => {
      setTimeout(() => {
        this.model.msg = '3rd step';
        this.model.step++;
        done();
      });
    }
  ];
  stepperFactory(this.model, this.steps);
}]

答案 1 :(得分:-1)

您可以使用服务来共享将maxStepstepProgress等作为参数的函数,而不是修改$scope,它们将返回更新的值。

在服务中:

function moveToPreviousStep(step) {
  if (step > 0) {
    return (step - 1);
  }
  return step;
};

并在控制器中

function moveToPreviousStep() {
  $scope.selectedStep = service.moveToPreviousStep($scope.selectedStep);
}
$scope.moveToPreviousStep = moveToPreviousStep;