【问题标题】:Angular: Height Change Not Detected角度:未检测到高度变化
【发布时间】:2016-06-04 16:59:20
【问题描述】:

我编写了一对指令,旨在在单击元素时将多个元素中的一个放大到更大的尺寸。单击缩放的元素应将其恢复为正常大小。当一个元素被缩放时,它的姊妹元素(它们都是 d3 图表)变得不可见。当放大的元素未缩放时,它们会恢复可见。

HTML 如下所示:

<chart-container class="chart" chart-height="400" >
    <h3 class="text-center">Vehicles by year</h3>
    <div class="text-center" full-screen-toggle>
        <bar-chart bar-data="{{vehiclesByYear}}"
                    layout="{{vehiclesByYearLayout}}"
                    bar-labels="{$dy: '-.5em', $anchor: 'middle'}"></bar-chart>
    </div>
</chart-container>
<chart-container class="chart" chart-height="400">
    <h3 class="text-center">Vehicle speed distribution</h3>
    <div class="text-center" full-screen-toggle>
        <pie-chart pie-data="{{aboveBelow}}"
                   layout="{{aboveBelowLayout}}"></pie-chart>
    </div>
</chart-container>

神奇之处在于元素指令chart-container 和属性指令full-screen-toggle。后者总是装饰图表容器内的子元素。这是两个指令的代码:

angular.module( 'MarkOlbert.fullScreenChart', [] ).directive( 'chartContainer', function () {
    return {
        restrict: 'E',
        scope: {
            chartHeight: '@chartHeight',
        },
        controller: ['$scope', '$element', '$rootScope', function ( $scope, $element, $rootScope ) {
            var zoomState = 'normal';
            var _self = this;

            this.changing = false;
            this.chartHeight = $scope.chartHeight;

            function unZoom() {
                $element.css('width', '50%' );

                _self.changing = true;
                $rootScope.$broadcast( 'chart:unzoom' );
                _self.changing = false;

                zoomState = 'normal';
            }

            function zoom() {
                $element.css( 'width', '100%' );

                _self.changing = true;
                $rootScope.$broadcast( 'chart:zoom' );
                _self.changing = false;

                zoomState = 'full';
            }

            $element.on( 'click', function () {
                switch ( zoomState ) {
                    case 'normal':
                        zoom();
                        break;

                    case 'full':
                        unZoom();
                        break;
                }
            } );

            $rootScope.$on( 'chart:unzoom', function () {
                if ( _self.changing ) return;

                $element.css( 'display', 'block' );
            } );

            $rootScope.$on( 'chart:zoom', function () {
                if ( _self.changing ) return;

                $element.css( 'display', 'none' );
            } );
        }],
    };
} );

angular.module( 'MarkOlbert.fullScreenToggle', [] ).directive( 'fullScreenToggle', function ($rootScope) {
    return {
        restrict: 'A',
        require: '^^chartContainer',
        link: function(scope,element,attrs, chartCtrl){
            element.css('height', chartCtrl.chartHeight );

            $rootScope.$on( 'chart:zoom', function () {
                if ( !chartCtrl.changing ) return;

                element.css( 'height', 1000 );
            } );

            $rootScope.$on( 'chart:unzoom', function () {
                element.css( 'height', chartCtrl.chartHeight );
            } );
        },
    };
} );

在条形图指令中,我有一个简单的手表,它应该响应条形图高度的变化:

    scope.$watch( function () { return element.height(); }, function () {
        if ( element.height() == 0 ) return;
    }, true );

现在它什么也没做,因为我试图弄清楚为什么当全屏切换改变高度时它没有被调用。

显示/隐藏功能按设计工作。 chart-container 和 full-screen-toggle 中的所有各种事件侦听器都会在它们应该调用的时候被调用,并且不会出错地执行。

当图表容器更改其元素的宽度时,页面会按预期更新。但是当全屏切换改变条形图的高度时,什么也没有发生。条形图中的 $watch 永远不会触发。

【问题讨论】:

    标签: javascript css angularjs


    【解决方案1】:

    .on() 是一个 jqLit​​e/jQuery 方法,不会自动触发 AngularJS 的摘要循环。

    现在发生的是:

    1. 元素被点击
    2. 调用缩放或取消缩放
    3. 元素的 CSS 已更改
    4. 事件被广播
    5. 通知广播事件的侦听器
    6. 元素的高度已更改

    但由于从未触发摘要循环,因此检查元素高度的观察者将永远不会执行,也不会检测到任何变化。

    你可以使用$apply:

    $element.on('click', function() {
      $scope.$apply(function() {
        switch (zoomState) {
          case 'normal':
            zoom();
            break;
    
          case 'full':
            unZoom();
            break;
        }
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2021-06-18
      • 2021-06-04
      • 1970-01-01
      • 2021-06-17
      • 2021-08-07
      • 2018-10-24
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多