简体   繁体   English

角表不会在价值变化时触发

[英]Angular watch does not fire on value change

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. 似乎在该服务设置了值之后控制台记录一次日志,但此后再也不会记录日志。 在此处输入图片说明
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: HTML带滑块的角材料:

<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>

I'm not entirely sure why your $watch isn't working, but might I suggest a different way to solve your problem. 我不完全确定为什么您的$ watch不能正常工作,但我可能会建议采用其他方法来解决您的问题。

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. 您可以从服务中初始化$ scope.brightness的值,但是一旦从滑块设置了它,就替换了该值,并且服务和范围不再相互绑定。 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. 相反,如果您从服务中初始化$ scope.image并为其设置值,则可以直接通过html中的绑定更新服务中的值。

Look at this codepen for examples of both scenarios: http://codepen.io/troylelandshields/pen/YXeLqG 查看此Codepen中的两种情况的示例: 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. 请注意,第二个示例中的$scope.$watch仅用于显示消息,完全没有必要更新服务。

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;
  })

})

I fixed the problem by changing the ng-models to image.brightness and image.contrast. 我通过将ng模型更改为image.brightness和image.contrast解决了该问题。 See $watch not firing on data change . 请参阅$ watch在数据更改时不触发 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. 我仍然不太了解,但是现在可以使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM