【发布时间】: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 更新。