【问题标题】:How to angular $watch element height after class change by model?如何在按模型更改类后调整 $watch 元素高度?
【发布时间】:2017-02-20 12:55:44
【问题描述】:

我已经阅读并尝试了关于角度 $watch() DOM 元素高度的每个线程,但无法弄清楚如何做到这一点。非常感谢任何帮助!

我有一个 Angular 应用程序,它通过更改模型值来更新简单的类名。示例:

class="theme-{{themeName}}"

当类更新时,DIV 会改变高度。

我想收到关于高度变化的回调。

我尝试使用 $watch() 和 $watch(..,,true) 并同时使用 angular.element()jquery ( $('foo')... )$digest 循环甚至从未调用 $watch 表达式。

更新(代码示例):

'use strict';

angular.module('k2')
.directive('k2', ['$rootScope', '$templateCache', '$timeout', 'lodash' ,'k2i',
function ($rootScope, $templateCache, $timeout, lodash, k2i) {
  return {
    restrict: 'E',
    template: $templateCache.get('k2/templates/k2.tpl.html'),
    replace: true,
    scope: {
      ngShow: '=',
      ngHide: '=',
      settings: '='
    },
    link: function(scope, elem, attrs) {
      k2i.initK2(scope, scope.settings || {});

      scope.$watch(function() {
        return $('.k2 .k2-template [k2-name]').height();
      }, function(newValue, oldValue, scope) {
        respondToChange(newValue, oldValue, scope);
      }, true);

      scope.$watch(function() {
        var kb = document.querySelectorAll('.k2 .k2-template [k2-name]')[0];
        var ab = document.querySelectorAll('.k2 .k2-template [k2-name] .k2-acc-bar')[0];
        var value = {
          kb: 0,
          ab: 0
        }
        if (kb) {
          value.kb = kb.clientHeight;
        }
        if (ab) {
          value.ab = ab.clientHeight;
        }
        return value;
      }, function(newValue, oldValue, scope) {
        respondToChange(newValue, oldValue, scope);
      }, true);

      function respondToChange(newValue, oldValue, scope) {
        if (newValue === oldValue) return;
        if (!scope.k2Pending) return;

        var kbNode = document.querySelectorAll('.k2 .k2-template [k2-name="' + scope.k2Pending.name + '"]');
        var abNode = document.querySelectorAll('.k2 .k2-template [k2-name="' + scope.k2Pending.name + '"] .k2-acc-bar');

        // Ensure required keyboard elements are in the DOM and have height.
        if ((kbNode.length > 0 && !scope.k2Pending.requiresAccessoryBar ||
           kbNode.length > 0 && abNode.length > 0 && scope.k2Pending.requiresAccessoryBar) &&

          (kbNode[0].clientHeight > 0 && !scope.k2Pending.requiresAccessoryBar ||
           kbNode[0].clientHeight > 0 && abNode[0].clientHeight > 0 && scope.k2Pending.requiresAccessoryBar)) {

          $rootScope.$emit('K2KeyboardInDOM', scope.k2Pending.name, getHeight());
        }
      };

      function getHeight() {
        var height = {};
        var kbElem = angular.element(document.querySelectorAll('.k2')[0]);

        var wasHidden = kbElem.hasClass('ng-hide');
        kbElem.removeClass('ng-hide');
        height[k2i.modes.NONE] = 0;
        height[k2i.modes.ALL] = document.querySelectorAll('.k2 .k2-template [k2-name="' + scope.k2Name + '"]')[0].clientHeight;
        height[k2i.modes.ACCESSORY_BAR_ONLY] = document.querySelectorAll('.k2 .k2-template [k2-name="' + scope.k2Name + '"] .k2-acc-bar')[0].clientHeight;
        height[k2i.modes.KEYBOARD_KEYS_ONLY] = height[k2i.modes.ALL] - height[k2i.modes.ACCESSORY_BAR_ONLY];
        if (wasHidden) {
          kbElem.addClass('ng-hide');
        }
        return height;
       };
     }
   }
 }
]);

【问题讨论】:

  • 发布你的代码,这样我们就可以真正看到问题出在哪里了..
  • FWIW,类名更新应该使用 ng-class 指令完成
  • @big_water - 谢谢;使用 ng-class 与模型属性是否会影响摘要循环的运行方式?我会试试这个并告诉你。
  • @DmitriAlgazin 谢谢,我真的在努力避免额外的属性,因为我正在创建一个框架并且要求用户添加额外的属性对我来说并不是特别有吸引力。不过,我会尝试一下。真的希望我能检测到 DOM 更新。

标签: html angularjs watch


【解决方案1】:

您应该只观察“themeName”变量。然后在 $timeout 中进行计算。应该需要 $timeout 来等待您的手动 DOM 更新。例如:

scope.$watch('k2Name', function(newValue, oldValue){
    $timeout(function(){
        //do what you want
    });
});

【讨论】:

  • 我已经使用了很多 $timeout() 的做法,但我仍然有点担心(特别是如果我必须添加时间值).. DOM 总是保证有到下一个摘要开始时已完全更新,因此样式更改已全部应用? (我需要最终高度)
  • Angular 不跟踪由另一个进程进行的 DOM 更新。所以也许你应该听 DOM 事件。但我认为超时是可以接受的。
  • 谢谢。我在没有 $timeout() 值的情况下尝试了这个(只是等到下一个周期),现在还为时过早,DOM 还没有更新。
  • 下一个循环在您更改应用状态或等待另一个自动按角度更改时开始。 $timeout 解决了这种情况。
猜你喜欢
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多