2013-07-09 44 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; 
      }); 
     } 
    } 
});