2

I have two sliders, one for brightness and another for contrast. Subsequently they are attached to a "brightness" model and a "contrast" model. These sliders are in a tab interface, any time the tab changed the value was getting reset. I decided to create a factory service to store the values and would like to update the factory with the new value anytime the sliders change. I know the slider models are being updated because I have a box next to each slider display the current value of the model. It seems to console log once after the value is set by the service but never logs afterwards. enter image description here
Controller Code:

'use strict';

angular.module('oct').controller('LeftCtrl', ['$scope', '$timeout', '$mdSidenav', '$log', 'OctSettings', function($scope, $timeout, $mdSidenav, $log, OctSettings) {
    $scope.resolutions = ['Resolution 1', 'Resolution 2', 'Resolution 3'];
    $scope.toggleDropdownArray = ['', '', '', ''];
    $scope.isThetaView = true;
    $scope.isCartView = true;
    $scope.isLongView = true;

    $scope.brightness = Number(OctSettings.image.brightness);
    $scope.contrast = Number(OctSettings.image.contrast);

    $scope.$watch('brightness',
        function(newVal, oldVal) {
            console.log(oldVal);
        });

    $scope.close = function() {
        $mdSidenav('left').close()
            .then(function() {
                $log.debug('close LEFT is done');
            });
    };

    $scope.toggleDropdown = function(index) {
        if($scope.toggleDropdownArray[index] === 'toggle-up') {
            $scope.toggleDropdownArray[index] = 'toggle-down';
        } else {
            $scope.toggleDropdownArray[index] = 'toggle-up';
            for(var i=0; i<$scope.toggleDropdownArray.length; i++) {
                if(i !== index) {
                    $scope.toggleDropdownArray[i] = 'toggle-down';
                }
            }
        }
    };
}]);

HTML w/ Angular Material for Sliders:

<md-tab label="Image">
    <md-content class="md-padding settings-tabs-pg-content">
        <div class="brightness-div" layout="">
            <div flex="10" layout="" layout-align="center center"><span class="md-body-1 fa fa-sun-o"><md-tooltip>Brightness</md-tooltip></span></div>
            <md-slider flex="" min="0" max="100" ng-model="brightness" aria-label="brightness" id="brightness-slider" class="">
            </md-slider>
            <div flex="20" layout="" layout-align="center center">
                <input type="number" ng-model="brightness" aria-label="brightness" aria-controls="brightness-slider">
            </div>
        </div>
        <div layout="">
            <div flex="10" layout="" layout-align="center center">
                <span class="md-body-1 fa fa-adjust"><md-tooltip>Contrast</md-tooltip></span>
            </div>
            <md-slider flex="" min="0" max="100" ng-model="contrast" aria-label="contrast" id="contrast-slider" class="">
            </md-slider>
            <div flex="20" layout="" layout-align="center center">
                <input type="number" ng-model="contrast" aria-label="contrast" aria-controls="contrast-slider">
            </div>
        </div>
        <div>
            <a class="window-leveling-btn">Window Leveling</a>
        </div>
    </md-content>
</md-tab>
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Daniel Kobe
  • 9,376
  • 15
  • 62
  • 109
  • I dont see anywhere in your code that you are actually updating the values in your service. Can you show where you bind to this value in your html? – shieldstroy Jul 02 '15 at 17:23
  • Ya, Id be updating the service where Im doing the console.log(oldVal). I removed it for testing, it didnt seem to make a difference. – Daniel Kobe Jul 02 '15 at 17:31

2 Answers2

3

I'm not entirely sure why your $watch isn't working, but might I suggest a different way to solve your problem.

You initialize the value of $scope.brightness from your service, but as soon as you set it from the slider you replace the value and the service and scope are no longer tied to each other. If instead you initialize $scope.image from your service and set values on that, then you can update the value in the service directly through the binding in your html.

Look at this codepen for examples of both scenarios: http://codepen.io/troylelandshields/pen/YXeLqG

Note that the $scope.$watch in the second example is only there to show the message, it is completely unnecessary to update the service.

angular.module('app', [])
.factory('fact', function(){
      return {
        image:{
          brightness:5
        }
      }
    })
.controller('ctrl', function($scope, fact){
  $scope.num = fact.image.brightness;

  $scope.image = fact.image;

  $scope.$watch('num', function(newVal, oldVal){
    $scope.msg = "Scope value: " + newVal + " , serviceVal: " + fact.image.brightness;
  })

  $scope.$watch('image.brightness', function(newVal, oldVal){
    $scope.msg = "Scope value: " + newVal + " , serviceVal: " + fact.image.brightness;
  })

})
shieldstroy
  • 1,307
  • 1
  • 10
  • 24
1

I fixed the problem by changing the ng-models to image.brightness and image.contrast. See $watch not firing on data change. I was aware of this issue but I thought because I was watching a number and not an object i didnt need to do this. I still dont quite understand, but it works now.

Community
  • 1
  • 1
Daniel Kobe
  • 9,376
  • 15
  • 62
  • 109