2016-10-11 55 views
1

我已閱讀並嘗試可能每個線程上的角度$watch() DOM元素的高度,但不能解決如何做到這一點。任何幫助是極大的讚賞!如何通過模型改變班級更改後的元素高度?

我有一個角度的應用程序,通過更改模型值來更新類的簡單名稱。例如:

class="theme-{{themeName}}" 

當類更新DIV更改高度。

我想收到高度變化的回調。

我試着使用$watch()和$觀看(.. ,,真)並同時使用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; 
     }; 
    } 
    } 
} 
]); 
+1

發佈您的代碼,這樣,我們其實可以看到的問題是.. – ZombieChowder

+1

FWIW,類名的更新應該使用納克級的指令 –

+0

這會有所幫助呢? http://stackoverflow.com/questions/19048985/angularjs-better-way-to-watch-for-height-change –

回答

0

您應該簡單地看 'THEMENAME' 變量。然後在$ timeout中進行計算。應該需要$ timeout來等待手動DOM更新。對於前:

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

我已經習慣了$ timeout()的做法有點但我仍然有點擔心(特別是如果我不得不添加一個時間值).. DOM總是保證在下一個摘要開始時全面更新,以便樣式更改全部應用? (我需要最終高度) –

+0

Angular不跟蹤另一個進程創建的DOM更新。所以也許你應該聽DOM事件。但我認爲超時是可以接受的。 –

+0

謝謝。我嘗試了這個沒有$ timeout()的值(只是等到下一個週期),它太早了,DOM尚未更新。 –