【问题标题】:How to manipulate styles of directive in AngularJS?如何在 AngularJS 中操作指令样式?
【发布时间】:2013-10-15 06:46:09
【问题描述】:

我正在使用 AngularJS 和 AngularJS 指令编写组件。

我正在做这样的事情:

var MyApp = angular.module('MyApp', []);

MyApp.directive('myTag', function() {
    return { /* Some logic here*/ }
});

我希望能够更改组件的样式(使用 CSS),如下所示:

<my-tag class="MyClass"></my-tag>

除此之外,我希望能够操纵我的所有元素样式 组件(my-tag 中的 HTML 标记)。

您对如何使用 AngularJS 操作自定义标签的样式属性有任何建议或有用的示例吗?

【问题讨论】:

  • 我不确定您对更改样式的确切含义。已经有ng-styleng-class 用于此。
  • 你说的是样式还是类?有很大的不同。操作类很容易。样式,没那么多。

标签: javascript html css angularjs angularjs-directive


【解决方案1】:

这应该可以解决问题。

var MyApp = angular.module('MyApp', []);

MyApp.directive('myTag', function() {
    return { 
      link: function(scope, element, attributes){
        element.addClass('MyClass');
      }
    }
});

【讨论】:

  • 所以,我必须在指令中添加一个类的名称,对吧?如果是这样,我认为这不是一个好的解决方案......
  • 也许这就是你想要的docs.angularjs.org/api/ng.directive:ngStyle
  • 为什么这会被点赞??该问题不问如何操作指令元素的类。
  • @dmr07 我赞成它以鼓励作者在将来使他的问题更清楚 - 因为这个答案基于他的标题对我有用:-)
【解决方案2】:

这是 AngularJS 添加核心 CSS 样式的方式:

angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>');

您可以在 angular.js v1.2.0-rc.2 中找到此代码。

编辑

在自定义指令中,我使用此解决方案将 CSS 样式表捆绑到指令中:

  var outputColorCSS = {
    selector: 'span.ouput-color',
    rules: [
        'display: inline-block',
        'height: 1em',
        'width: 5em',
        'background: transparent',
        'border: 3px solid black',
        'text-align: center',
        'font-weight: bold',
        'font-size: 0.8em'
    ]
  };
  var outputColorStyleSheet = outputColorCSS.selector + outputColorCSS.rules.join(';');
  angular.element(document).find('head').prepend('<style type="text/css">' + outputColorStyleSheet + '</style>');

然后你可以在你的指令模板中使用class="ouput-color"

我发现它非常干净和有用。

【讨论】:

  • 干得好,不过我不得不添加大括号:... outputColorCSS.selector + '{' + outputColorCSS.rules.join(';') + '}';
  • 澄清一下:这段代码是纯 javascript,不能放在你的 link() 函数中,否则在每次使用你的指令时,&lt;style&gt; 块将被添加到 &lt;head&gt;
  • 这给了我一个想法:在样式标签上放一个 id 并检查它是否已经存在会不会太糟糕??
【解决方案3】:

我参加聚会有点晚了,但是你们为什么不都使用内置的 .css() 方法?

只需使用:

link: function(scope, elem, attr, ctrl)
{
    elem.css({'display': 'block', 'height': '100%', 'width': '100%'});

}

或任何你想要的 CSS。

【讨论】:

  • 您能否提供更多详细信息,也许我可以帮助您弄清楚为什么它不起作用? jQlite 默认在 Angular 上可用。它包括 .css() 函数。 docs.angularjs.org/api/ng/function/angular.elementapi.jquery.com/css
  • 现在可以使用了。我对元素的内联样式进行了 ng-binding。我在初始链接期间拥有的 css 被后来的绑定覆盖。感谢您的回复。
  • 需要$(elem[0]).css({...})
  • @SoldeplataSaketos 我认为你错了,我只是仔细检查了一下,“css”方法确实在 elem 上,而不必将其包装在 jquery 元素中。 Elem 已经是一个 jquery-lite 元素。
【解决方案4】:

您可以将自定义样式放入带有参数的指令声明中,就像您举例说明的那样。

为了声明这样的样式,您必须定义一个变量来保存自定义样式:

scope: {
    myClass: '@myClass'
  },

然后在指令的模板中设置该参数,如下所示:

<my-tag my-class="CustomClass"></my-tag>

最后,在指令本身的模板中,引用那个类:

<h1 class="{{myClass}}">{{myContent}}</h1>

我制作了一个插件,展示了如何在指令check it out here 中自定义样式。

【讨论】:

  • 如果属性没有设置,我可以设置一个默认值吗?
  • plnkr 的链接在哪里?
【解决方案5】:

Plunker

要通过属性指令操作 css 样式,您可以执行以下操作:

var app = angular.module('colorSwap', []);

app.directive('styleChanger', function() {
  return {
    'scope': false,
    'link': function(scope, element, attrs) {
      var someFunc = function(data)
      {
        /* does some logic */
        return 'background-color:' + data;
      }
      var newStyle = attrs.styleChanger;
      scope.$watch(newStyle, function (style) {
        if (!style) {
          return ;
        }
        attrs.$set('style', someFunc(style));
      });
    }
  };
});

一些html:

<div ng-app="colorSwap">
  <input type="txt" ng-init="colorName= 'yellow'" ng-model="colorName" />
  <div style-changer="colorName">this is the div content</div>
</div>

要制作一个元素指令,改变它自己的风格,像这样:

app.directive('elementWithStyle', function() {
  return {
    'restrict' : 'E',
    'scope': {},
    'controller': function($scope) {
      $scope.someStyle = 'Cyan';
      $scope.someFunc = function() { $scope.someStyle = 'purple' };
    },
    'template': '<div style="background: {{someStyle}}" ng-click="someFunc()"> click me to change colors </div>'
  }
});

还有html:

<div ng-app="colorSwap">
  <element-with-style>123</element-with-style>
</div>

我希望这会有所帮助。其余答案或多或少涉及类操作。

【讨论】:

    【解决方案6】:

    要在指令的子项中进行 css 操作,请尝试以下操作:

    var MyApp = angular.module('MyApp', []);
    
    MyApp.directive('myTag', function() {
        return { 
          link: function(scope, element, attr){
    
           // For your tag
           element.addClass('MyClass');
    
           // For elements inside your directive tag
           var tag_childs = element[0].childNodes;
           for(var i = 0; i < element[0].childElementCount; i++){
    
              tag_childs[i].style.height = '70px';
    
            }
    
          }
        }
    });
    

    【讨论】:

      【解决方案7】:

      这是一个示例,请注意这可能不是 AngularJS 的最佳用途,因为是声明性的,您可能只想将类放在标记上。但是,为了让您了解发生了什么,让我演示一个简单的指令来执行您最初要求的操作。

      var MyApp = angular.module('MyApp', []);
      
      MyApp.directive('myTag', function($compile) {
          return {
              restrict: 'E', // this means it will be an element
              link: function(scope, element, attrs, ctrl) {
                  // First, I included the $compile service because it will be needed
                  // to compile any markup you want to return to the element.
      
                  // 1. Add the class, as you wanted
                  element.addClass('MyClass');
      
                  // 2. Add markup
                  var html = '<div>Hello World</div>';
                  //Compile it and add it back
                  $compile(html)(scope);
                  element.html(html);
              }
          };
      });
      

      最后,在您的标记中,您只需将其放入:

      <my-tag />
      

      【讨论】:

      • 好的。但问题仍然悬而未决 - 我是否需要将自定义类的名称“MyClass”放入指令声明中?这不是一个好的解决方案,我尽量避免它。如何做同样的事情,但通过一些参数?
      • 你仍然可以把课放在外面。指令仅在 replace: true 声明时替换内容。
      【解决方案8】:

      app.directive('bookslist', function() {
      
          return {
          	scope: true,
              templateUrl: 'templates/bookslist.html',
              restrict: "E",
              controller: function($scope){
      
              },
              link: function(scope, element, attributes){
              element.addClass('customClass');
            }
      
          }
      
      });
      .customClass table{
      	background: tan;
      
      }
      .customClass td{
      	border: 1px solid #ddd;
      
      }
      <!DOCTYPE html>
      <html>
      
      <head>
          <link href="app.css" rel="stylesheet">
          <script type="text/javascript" src="angular.min.js"></script>
          <script type="text/javascript" src="app.js"></script>
          <title>Task</title>
      </head>
      
      <body ng-app="app">
          <div ng-controller="myCtrl">
            
               <bookslist></bookslist>
      
      
          </div>
      </body>
      
      </html>

      【讨论】:

      • 感谢您的回答。请编辑。 好的答案将始终解释所做的事情以及为什么以这种方式完成,不仅适用于 OP,而且适用于 SO 的未来访问者。
      【解决方案9】:

      角度

      app.directive("time",function(){
                  var directive={};
                  directive.restrict="A";
                  directive.link=function(scope,element,attr,ctrl){                   
                      element.css({
                          backgroundColor:'#ead333'
                      });
                  }
                  var time=new Date().toTimeString();
                  directive.template=time;
                  return directive;
              });
      

      HTML

      The times is <span time></span>
      

      【讨论】:

        【解决方案10】:

        我还没有找到完美的解决方案,但即使有指令,我也会关注 John Papa's styling 的控制器:

        • 指令是一个文件夹 (directiveName.directive)
        • 里面有3个文件:directiveName.directive.js、directiveName.template.html、directiveName.styles.css
        • 在声明指令时使用 templateUrl。和往常一样,模板有指向 css 文件的链接

        我发现它非常干净并且遵循一种模式。不利的一面是,您在呈现的 HTML 中的指令附近创建了几个 &lt;link&gt; 标记(不过,这似乎仍然不是问题)。也请查看this comment

        话虽如此,看看Angular 1.5 component's。它相对较新,并且有更好的方法。现在我只将指令用于 DOM 操作(而不是作为组件的可重用性)。

        【讨论】:

          猜你喜欢
          • 2013-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-30
          • 2017-01-23
          • 2014-06-02
          • 2016-01-03
          • 1970-01-01
          相关资源
          最近更新 更多