【问题标题】:Window resize directive窗口调整大小指令
【发布时间】:2014-05-27 11:35:32
【问题描述】:

我试图在窗口调整大小时调整 div 大小,环顾四周后,似乎使用指令是最好的解决方案。

模板:

<div elHeightResize ng-view ng-style="{ height: windowHeight }"></div>

指令:

myApp.directive('elheightresize', ['$window', function($window) {
    return {
        link: function(scope, elem, attrs) {
            scope.onResize = function() {
                var header = document.getElementsByTagName('header')[0];
                elem.windowHeight = $window.innerHeight - header.clientHeight;
            }
            scope.onResize();

            angular.element($window).bind('resize', function() {
                scope.onResize();
            })
        }
    }
}])

虽然我可以在scope.onResize 中记录elem.windowHeight,但它似乎不适用于ngStyle

我还是忽略了什么吗?

编辑:

&lt;div ng-view resize style="height: {{ windowHeight }}px"&gt;

这个解决方案似乎有效,但仍然对使用 ngStyle 不起作用的原因感兴趣。

【问题讨论】:

  • 您的确切问题的答案(为什么elem.windowHeight 不适用于ngStyle)是您必须通过触发摘要循环手动应用它,因为.bind() 方法不是被 Angular 拦截。因此,在事件处理程序的末尾(scope.onResize(); }) 之后)您应该添加 scope.$apply();

标签: angularjs resize window


【解决方案1】:

我想你忘了在 scope.onResize 方法结束时调用 scope.$apply(); 来触发摘要循环

无论如何,我使用了以下对我有用的指令(取自 HERE):

尝试打开调试视图并更改视图高度:Demo Fiddle

app.directive('resize', function ($window) {
    return function (scope, element, attr) {

        var w = angular.element($window);
        scope.$watch(function () {
            return {
                'h': w.height(), 
                'w': w.width()
            };
        }, function (newValue, oldValue) {
            scope.windowHeight = newValue.h;
            scope.windowWidth = newValue.w;

            scope.resizeWithOffset = function (offsetH) {

                scope.$eval(attr.notifier);

                return { 
                    'height': (newValue.h - offsetH) + 'px'
                    //,'width': (newValue.w - 100) + 'px' 
                };
            };

        }, true);

        w.bind('resize', function () {
            scope.$apply();
        });
    }
}); 

及用法:

 <div  ng-style="resizeWithOffset(165)" 
       resize 
        notifier="notifyServiceOnChage(params)"
   >
    /** ... */
 </div>

虚拟控制器方法用法:

$scope.notifyServiceOnChage = function(){
      console.log($scope.windowHeight);   
 };

[编辑]

这里是使用innerHeight的没有jQuery库的演示

演示3Fiddle

【讨论】:

  • 这很奇怪,当复制/粘贴您的代码时,我似乎什么也没发生。然后我尝试自行分离我的代码,它可以工作:jsfiddle.net/zbjLh/272 似乎它们可能是我的应用程序中的一些冲突,尽管那里没有发生什么特别的事情。
  • 当我这样做 &lt;div ng-view resize style="height: {{ windowHeight }}px"&gt; 它似乎工作......
  • 我对为什么我的代码不起作用很感兴趣,我可以复制/粘贴您的代码,但这并不能解决我最初的问题。
  • 如果您想找到问题,请尝试在 Fiddle 中重现错误
  • 对于阅读本文的其他人,我认为调用.height().width() 假定w(或angular.element($window) 的结果)是一个JQuery 对象。换句话说,这需要 jQuery 在页面上。仅使用 jqLit​​e 时似乎不起作用
【解决方案2】:

由于我们使用指令,我们总是可以通过改变指令内元素的高度来进行一些 DOM 操作。

例子:

var app=angular.module('App', []);
app.directive('elheightresize', ['$window', function($window) {
    return {
        link: function(scope, elem, attrs) {
            scope.onResize = function() {
                var header = document.getElementsByTagName('header')[0];
                elem.windowHeight = $window.innerHeight - header.clientHeight;
                $(elem).height(elem.windowHeight);
            }
            scope.onResize();

            angular.element($window).bind('resize', function() {
                scope.onResize();
            })
        }
    }
}])

现场示例:http://jsfiddle.net/choroshin/FJvyb/

【讨论】:

  • 虽然这可行,但我仍然对为什么我的代码不起作用感兴趣。
  • 回答这个问题可能为时已晚,但万一有人遇到这个问题,上面的例子有一个错误:调整大小的移动并不总是导致 div 填充整个区域并定期
    元素将只是文本的高度。您需要在scope.onResize(); 调用之后添加scope.apply();,以确保正确传播更改。
【解决方案3】:

自从您询问以来已经有一段时间了,您似乎已经找到了解决方法...... 但你也问为什么ng-style 不起作用:

ng 风格,来自 Angular 文档

表达式,它评估一个对象,其键是 CSS 样式名称,值是这些 CSS 键的对应值。

因此,在您提供的 ng 样式示例中 height : 375; (也就是说,如果 windowHeight 评估为 375)并且这不是一个合适的值。

它应该就像你在你的解决方法中所做的那样并且有单位。

windowHeight = ($window.innerHeight - header.clientHeight) + "px";

【讨论】:

    【解决方案4】:

    CoffeeScript 中的极简风格:

    app.directive "applyOnResize", ($window) ->
      ($scope, $element) ->
        $element($window).bind("resize", $scope.$apply)
    

    Same in Javascript.

    【讨论】:

      【解决方案5】:

      内部链接函数给出

      scope.onResize = function() {
                  var header = document.getElementsByTagName('header')[0];
                  elem.windowHeight = $window.innerHeight - header.clientHeight;
              }
      
      
      $window.onresize = function(){scope.onResize();scope.$apply();}
      

      【讨论】:

      • 您是否需要在某个时候删除调整大小事件处理程序?
      【解决方案6】:

      这是另一个版本,没有使用 angular $watch,只是想观察窗口大小的变化:

      function resize () {
      
              var windowHeight = window.innerHeight,
                  windowWidth  = window.innerWidth;
      
              scope.windowHeight = windowHeight;
              scope.windowWidth  = windowWidth;
      
              console.log('w.innerHeight', windowHeight);
              console.log('w.innerWidth', windowWidth);
      
              //** If want to apply style on element, can do something like:
              var elemStyle = {
                  width: windowWidth + 'px',
                  height: windowHeight + 'px'
              };
      
              element.css(elemStyle);
          }       
          resize();
      
          //** On resize
          window.onresize = function () {
              resize();
              scope.$apply();
          }
      
          //** Destroy
          scope.$on('$destory', function () {
              window.off('resize')
          });  
      

      Fiddle

      【讨论】:

      • 这是不好的做法...全局 onresize 处理程序等使用其他答案中的代码
      • 我只是给出替代建议以在不使用 $watch 的情况下实现结果,这就是我编写/扩展代码示例的原因。我相信我确实解释清楚了。顺便说一句,全局 onrpsize 处理程序没有问题 imo,只取决于您如何使用它。一次考虑多个对话。您可能担心全局处理程序将始终监听事件更改。但是角度指令可以随时销毁/删除。指令监听的范围无论如何都不会是“全局”范围/模块。
      猜你喜欢
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 2019-05-15
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多