-->

Unable to reset a $scope variable with angularjs

2019-09-19 05:22发布

问题:

I have a factory that is injected into all of my controllers to initialize and store the state.

state.js

angular.module('c2gyoApp')
  .factory('state', function() {

    var now = new moment().startOf('hour');

    return {
      rental: {
        tab: 'simple',
        startDate: now.clone().add(1, 'h'),
        endDate: now.clone().add(10, 'h'),
        distance: 10,
        timeMinutes: 0,
        timeHours: 10,
        timeDays: 0,
        timeWeeks: 0,
        timeStanding: 0,
        airport: false
      }
    };
  });

The start of every controller looks like this

c2gdtp.js

angular.module('c2gyoApp')
  .controller('C2gdtpCtrl', [
    '$scope',
    'c2gConfig',
    'duration',
    'state',
    function($scope, config, duration, state) {
      $scope.rental = state.rental;
      ...
    }
  ]);

This works just as intendend throughout the different controllers. Every change made to the $state.rental object is kept through different views/controllers.

I've implemented a clear() function in a directive that is used by every controller:

timeinputform.js

angular.module('c2gyoApp')
  .directive('timeInputForm', function() {
    return {
      restrict: 'E',
      templateUrl: 'scripts/directives/timeInputForm.html',
      controller: function($scope) {
        ...
        $scope.clear = function() {
          var now = new moment().startOf('hour').add(1, 'h');

          $scope.rental = {
            startDate: now.clone(),
            endDate: now.clone(),
            distance: 0,
            timeMinutes: 0,
            timeHours: 0,
            timeDays: 0,
            timeWeeks: 0,
            timeStanding: 0,
            airport: false
          };

          angular.copy($scope.rental);
        };

      }
    };
  });

Problem is it doesn't save the reset of the $state.rental object. For example, if I'm in view1/controller1 and click the clear button, the $state.rental object is reset. If I change onto view2/controller2 I have the same old values as before I clicked the clear button. If I then go again to view1/controller1, I also have the same old values from before, although I clicked the clear button.

The clear() function is in the directive because that's where the clear button is located. I've tried copying the clear function into the controllers, with the same result.

I just want to clear the state throughout all the controllers. What's the trick for this?

edit @zeroflagL How would a clean solution look like? I've tried setting up the clearRental function in the factory:

edit#2 My final solution. The tab value has to stay the same, and I couldn't take it out of the $scope anymore in the factory. Now it's being passed on.

state.js

angular.module('c2gyoApp')
  .factory('state', function() {

    var now = new moment().startOf('hour');

    var rental = {
      tab: 'simple',
      startDate: now.clone().add(1, 'h'),
      endDate: now.clone().add(10, 'h'),
      distance: 10,
      timeMinutes: 0,
      timeHours: 10,
      timeDays: 0,
      timeWeeks: 0,
      timeStanding: 0,
      airport: false
    };

    var clearRental = function(currenttab) {
      var now = new moment().startOf('hour').add(1, 'h');

      var rental = {
        tab: currenttab,
        startDate: now.clone(),
        endDate: now.clone(),
        distance: 0,
        timeMinutes: 0,
        timeHours: 0,
        timeDays: 0,
        timeWeeks: 0,
        timeStanding: 0,
        airport: false
      };

      angular.copy(rental, this.rental);
    };

    return {
      rental: rental,
      clearRental: clearRental
    };
  });

the controllers:

c2gdtp.js

angular.module('c2gyoApp')
  .controller('SmdtpCtrl', [
    '$scope',
    'stadtmobilRates',
    'smConfig',
    'duration',
    'state',
    function($scope, stadtmobilRates, smConfig, duration, state) {
      $scope.rental = state.rental;
      $scope.clear = function() {
        state.clearRental($scope.rental.tab);
      };
      ...
    }
  ]);

回答1:

$scope.rental = {
        tab: $scope.rental.tab,

This assigns a new object to $scope.rental which has no association to state.rental.

angular.copy($scope.rental)

Does essentially nothing. You need to assign back the changes:

angular.copy($scope.rental, state.rental);

The cleaner solution, of course, would be to have a state.clearRental method that is called by the controller.

EDIT

As for the cleaner solution:

clearRental: function() {
    var now = new moment().startOf('hour').add(1, 'h');

    var rental = { ...};
    angular.copy(rental, this.rental);

$scope.clear = function() {
    state.clearRental();
};


回答2:

You can call state in the directive:

angular.module('c2gyoApp')
  .directive('timeInputForm', ['state', function(state) {
    return {
      restrict: 'E',
      templateUrl: 'scripts/directives/timeInputForm.html',
      controller: function($scope) {
        ...
        $scope.clear = function() {
          var now = new moment().startOf('hour').add(1, 'h');

          state.rental = $scope.rental = {
            tab: $scope.rental.tab,
            startDate: now.clone(),
            endDate: now.clone(),
            distance: 0,
            timeMinutes: 0,
            timeHours: 0,
            timeDays: 0,
            timeWeeks: 0,
            timeStanding: 0,
            airport: false
          };

          angular.copy($scope.rental);
        };

      }
    };
  }]);