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/

4

4 に答える 4

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
        }
    }   
}];
于 2013-12-24T13:06:04.167 に答える
1

あなたが直面する問題は、getComputedStyle が非常に遅い実行メソッドと見なされることです。そのため、特に getComputedStyle が変更されるたびに angularjs にビューを更新させたい場合は、それを使用するとパフォーマンスの問題が発生します。

また、 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;
            });
        }
    }
});
于 2013-07-10T02:32:06.947 に答える
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;

すべてのフィドル ファイルを検索することなく、ブレークポイントにドロップするコード内のステートメント。

もう1つのクイックアップデート

以下のコードは、AngularUI チームの Boostrap-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;
}]);
于 2013-07-09T20:04:03.317 に答える
0

この解決策は、子要素にディレクティブが必要ない場合に機能します。ng-repeat 要素自体に宣言を配置するだけで、ソリューションは機能します。

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

フィドル

于 2013-07-09T17:48:29.387 に答える