Angular 手表不会在值更改时触发

Posted

技术标签:

【中文标题】Angular 手表不会在值更改时触发【英文标题】:Angular watch does not fire on value change 【发布时间】:2015-09-20 08:15:57 【问题描述】:

我有两个滑块,一个用于亮度,另一个用于对比度。随后将它们附加到“亮度”模型和“对比度”模型。这些滑块位于选项卡界面中,任何时候选项卡更改值都会重置。我决定创建一个工厂服务来存储值,并希望在滑块更改时使用新值更新工厂。我知道滑块模型正在更新,因为每个滑块旁边都有一个框显示模型的当前值。在服务设置值后似乎控制台日志一次,但之后从不记录。 控制器代码:

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

【问题讨论】:

我在您的代码中没有看到您实际上正在更新服务中的值。你能在你的 html 中显示你绑定到这个值的位置吗? 是的,我正在更新我正在执行 console.log(oldVal) 的服务。我删除它进行测试,它似乎没有任何区别。 【参考方案1】:

我不完全确定您的 $watch 为何不工作,但我能否建议一种不同的方法来解决您的问题。

您从您的服务初始化 $scope.brightness 的值,但是一旦您从滑块设置它,您替换该值和服务和范围不再相互关联。相反,如果您从服务中初始化 $scope.image 并为其设置值,那么您可以直接通过 html 中的绑定来更新服务中的值。

查看此代码笔以了解两种情况的示例:http://codepen.io/troylelandshields/pen/YXeLqG

请注意,第二个示例中的$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;
  )

)

【讨论】:

好建议!我不知道你能做到。【参考方案2】:

我通过将 ng-models 更改为 image.brightness 和 image.contrast 解决了这个问题。见$watch not firing on data change。我意识到了这个问题,但我认为因为我在看一个数字而不是一个我不需要这样做的对象。我还是不太明白,但是现在可以了。

【讨论】:

以上是关于Angular 手表不会在值更改时触发的主要内容,如果未能解决你的问题,请参考以下文章

ocaml,能够在值更改时触发编译错误

地理位置手表不会持续触发

React 组件不会在值更改时重新渲染并显示 CSS 更改

表单组值更改时不会触发更改检测

在 Angular 4 中,钩子 ngOnChanges 不会在输入时触发

AngularFire 不会触发更改检测