2013-07-09 83 views
3

我相信這將是一個「不這樣做!」但我試圖在角元素上顯示樣式。從角度指令訪問元素樣式

<div ng-repeat="x in ['blue', 'green']" class="{{x}}"> 
     <h3 insert-style>{{theStyle['background-color']}}</h3> 
</div> 

結果將是

<div class='blue'><h3>blue(psudeo code hex code)</h3></div> 
<div class='green'><h3>green(psudeo code hex code)</h3></div> 

我基本上需要得到樣式屬性並顯示出來。

指令代碼...

directives.insertStyle = [ function(){ 
    return { 
     link: function(scope, element, attrs) { 
      scope.theStyle = window.getComputedStyle(element[0], null); 
     } 
} 
}]; 

小提琴例如:http://jsfiddle.net/ncapito/G33PE/

+1

不要這樣做(使用控制器)!使用指令! –

+0

所以你的建議只是創建一個插入樣式值的指令。 – Nix

+0

同意該指令。 – rGil

回答

6

我的最終解決方案(使用一個道具沒有工作,但是當我使用整個OBJ它的工作原理精)...

標記

<div insert-style class="box blue"> 
    <h4 > {{ theStyle['color'] | toHex}} </h4> 
</div> 

指令

directives.insertStyle = [ "$window", function($window){ 
    return { 
     link: function(scope, element, attrs) { 
      var elementStyleMap = $window.getComputedStyle(element[0], null); 
      scope.theStyle = elementStyleMap 
     } 
    } 
}]; 
+1

這是跨瀏覽器嗎? –

0

此解決方案,如果你沒有擁有的子元素的指令工作。如果你只是放置NG-repeat元素本身的聲明,您的解決方案的工作原理:

<div insert-style ng-repeat="x in ['blue', 'green']" class="{{x}}"> 

Fiddle

+0

請看我的小提琴,我正在嘗試獲取*風格*。我把它弄昏了。 – Nix

+0

所以我想出了爲什麼你的作品和我的更復雜的解決方案沒有,這是因爲在指令中我返回用戶指定的樣式。在你的情況/我的例子中,我將地圖返回到視圖,該視圖有時間處理getComputedStyle – Nix

1

尤里卡!

http://jsfiddle.net/G33PE/5/

var leanwxApp = angular.module('LeanwxApp', [], function() {}); 

var controllers = {}; 
var directives = {}; 
directives.insertStyle = [ function(){ 
    return { 
     link: function(scope, element, attrs) { 
      scope.theStyle = window.getComputedStyle(element[0].parentElement, null) 
     } 
} 
}]; 

leanwxApp.controller(controllers); 
leanwxApp.directive(directives); 

使剛剛拍了很多持久性和猜測。也許超時是不必要的,但在調試時,似乎我只在超時發生後才從父級獲取樣式值。

而且我不知道爲什麼,但我不得不去到parentElement獲取其風格(即使它現實地繼承(聳肩)?)

更新小提琴再次

有沒有一個沒有超時,但只是看着風格的parentElement,它似乎仍然工作,所以抓住風格不可用的懷疑,它只是沒有在我所期望的。

而且聖牛有很多的在Chrome瀏覽器來調試: https://developers.google.com/chrome-developer-tools/docs/javascript-debugging

我使用的代碼

debugger; 

聲明中斷點下降,而無需搜索所有的小提琴文件。

一個更快更新

下面的代碼從AngularUI隊出來的自舉的UI,並聲稱提供觀看相應的事件的手段(有沒有試過,但它看起來像它應該幫幫我)。

http://angular-ui.github.io/bootstrap/

/** 
* $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete. 
* @param {DOMElement} element The DOMElement that will be animated. 
* @param {string|object|function} trigger The thing that will cause the transition to start: 
* - As a string, it represents the css class to be added to the element. 
* - As an object, it represents a hash of style attributes to be applied to the element. 
* - As a function, it represents a function to be called that will cause the transition to occur. 
* @return {Promise} A promise that is resolved when the transition finishes. 
*/ 
.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) { 

    var $transition = function(element, trigger, options) { 
    options = options || {}; 
    var deferred = $q.defer(); 
    var endEventName = $transition[options.animation ? "animationEndEventName" : "transitionEndEventName"]; 

    var transitionEndHandler = function(event) { 
     $rootScope.$apply(function() { 
     element.unbind(endEventName, transitionEndHandler); 
     deferred.resolve(element); 
     }); 
    }; 

    if (endEventName) { 
     element.bind(endEventName, transitionEndHandler); 
    } 

    // Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur 
    $timeout(function() { 
     if (angular.isString(trigger)) { 
     element.addClass(trigger); 
     } else if (angular.isFunction(trigger)) { 
     trigger(element); 
     } else if (angular.isObject(trigger)) { 
     element.css(trigger); 
     } 
     //If browser does not support transitions, instantly resolve 
     if (!endEventName) { 
     deferred.resolve(element); 
     } 
    }); 

    // Add our custom cancel function to the promise that is returned 
    // We can call this if we are about to run a new transition, which we know will prevent this transition from ending, 
    // i.e. it will therefore never raise a transitionEnd event for that transition 
    deferred.promise.cancel = function() { 
     if (endEventName) { 
     element.unbind(endEventName, transitionEndHandler); 
     } 
     deferred.reject('Transition cancelled'); 
    }; 

    return deferred.promise; 
    }; 

    // Work out the name of the transitionEnd event 
    var transElement = document.createElement('trans'); 
    var transitionEndEventNames = { 
    'WebkitTransition': 'webkitTransitionEnd', 
    'MozTransition': 'transitionend', 
    'OTransition': 'oTransitionEnd', 
    'transition': 'transitionend' 
    }; 
    var animationEndEventNames = { 
    'WebkitTransition': 'webkitAnimationEnd', 
    'MozTransition': 'animationend', 
    'OTransition': 'oAnimationEnd', 
    'transition': 'animationend' 
    }; 
    function findEndEventName(endEventNames) { 
    for (var name in endEventNames){ 
     if (transElement.style[name] !== undefined) { 
     return endEventNames[name]; 
     } 
    } 
    } 
    $transition.transitionEndEventName = findEndEventName(transitionEndEventNames); 
    $transition.animationEndEventName = findEndEventName(animationEndEventNames); 
    return $transition; 
}]); 
+0

不能說我信任它,我癱倒在小提琴上並取出了孩子。而且它不起作用http://jsfiddle.net/ncapito/MVesL/讓我去做父母的事情是做一些奇怪的事情。 – Nix

+1

我同意這絕對是奇怪的,在這裏沒有多少意義,但至少得到了某種答案,所以在沒有任何線索發生什麼事情後興奮起來。希望你找到一個真正的解決方案,我必須繼續做一些事情,祝你好運。 – shaunhusain

1

你要面對的是,是的getComputedStyle認爲是一個非常緩慢的運行方式,所以你如果使用遇到的性能問題,特別是如果你想angularjs更新視圖時的問題getComputedStyle更改。

此外,getComputedStyle將解決每一個可能的樣式聲明,我認爲這不會很有用。所以我認爲需要一種減少可能風格數量的方法。

絕對認爲這是一個反模式,但是如果你仍然堅持在這個愚蠢:

module.directive('getStyleProperty', function($window){ 
    return { 
     //Child scope so properties are not leaked to parent 
     scope : true, 
     link : function(scope, element, attr){ 
      //A map of styles you are interested in 
      var styleProperties = ['text', 'border']; 
      scope.$watch(function(){ 
       //A watch function to get the styles 
       //Since this runs every single time there is an angularjs loop, this would not be a very performant way to do this 
       var obj = {}; 
       var computedStyle = $window.getComputedStyle(element[0]); 
       angular.forEach(styleProperties, function(value){ 
        obj[value] = computedStyle.getPropertyValue(value); 
       }); 
       return obj; 
      }, function(newValue){ 
       scope.theStyle = newValue; 
      }); 
     } 
    } 
});