【问题标题】:Controller-independent stepper functions独立于控制器的步进功能
【发布时间】:2016-09-20 12:04:55
【问题描述】:

我有一个 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。

谢谢。

【问题讨论】:

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


    【解决方案1】:

    将该功能抽象到一个接受回调数组和控制器的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);
    }]
    

    【讨论】:

    • 您好,谢谢您的回答。你能告诉我这些超时和(done) 的目的吗?
    【解决方案2】:

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

    在役:

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

    在控制器中

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

    【讨论】:

    • 是的,我已经考虑过那个替代方案,但它仍然不够 DRY,我还不如坚持当前的复制。
    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    相关资源
    最近更新 更多