Angularjs 从角度指令访问元素样式

Angularjs 从角度指令访问元素样式,angularjs,Angularjs,我确信这将是一个“不要那样做!”但是我试图在一个有角度的元素上显示样式 <div ng-repeat="x in ['blue', 'green']" class="{{x}}"> <h3 insert-style>{{theStyle['background-color']}}</h3> </div> Fiddle示例:如果您不必在子元素上具有指令,则此解决方案有效。如果您只是将声明放在ng repeat元素本身上,那么您的解决

我确信这将是一个“不要那样做!”但是我试图在一个有角度的元素上显示样式

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

Fiddle示例:

如果您不必在子元素上具有指令,则此解决方案有效。如果您只是将声明放在ng repeat元素本身上,那么您的解决方案可以工作:

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

万岁

所以这需要很多的坚持和猜测。也许超时是不必要的,但在调试时,我似乎只在超时发生后从父级获取样式值

我也不知道为什么,但我必须转到parentElement以获得样式(即使它实际上是继承的(耸耸肩)?)

再次更新小提琴

我做了一个没有超时的,但是只是查看样式的parentElement,它似乎仍然有效,所以请消除对样式根本不可用的怀疑,它只是在我期望的地方不可用

另外,Chrome中有很多调试方法:

我曾经

debugger;
代码中的语句可以插入断点,而不必搜索所有fiddle文件

再快速更新一次

下面的代码来自AngularUI团队的Boostrap UI,并声称提供了一种观看适当事件的方法(还没有尝试过这种方法,但看起来应该会有所帮助)


您将面临的问题是,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;
            });
        }
    }
});
我的最终解决方案(使用单个道具不起作用,但当我使用整个obj时,效果很好)

加价


不要(用控制器)那样做!使用指令!因此,您的建议是创建一个插入样式值的指令。同意该指令。删除我的答案,因为它没有“回答问题;”@rGil我试图使用指令,但出现订购问题。请看我的小提琴,我正在尝试获得样式。我把它简化了,所以我明白了为什么你的解决方案有效而我更复杂的解决方案无效,这是因为在指令中我返回了用户指定的样式。在您/我的示例中,我将地图返回到视图,该视图有时间处理GetComputedStyle。如果不能说我信任它,我将小提琴放低,并移除了该子对象。这不管用,让我觉得去找父母是件奇怪的事。我同意这肯定很奇怪,也没有什么意义,但至少得到了某种答案,所以在不知道发生了什么之后,我很兴奋。希望你能找到一个真正的解决方案,不过我得继续做一些事情,祝你好运。这是跨浏览器吗?
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);
debugger;
/**
 * $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;
}]);
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;
            });
        }
    }
});
<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
        }
    }   
}];