Angularjs使用指令动态添加引导程序类

Angularjs add bootstrap classes dynamically using directive

本文关键字:添加 引导程序 动态 指令 Angularjs      更新时间:2023-09-26

我们正在应用程序中实现可重用代码,为此,我们创建了一个显示内容的简单指令。

指令代码:

angular.module("newsStore.moduleDirectives", [])
    .directive('renderAboutContent', ['aboutService', renderAboutContent]);
function renderAboutContent(aboutService) {
    return {
        restrict: 'AE',
        scope: {},
        templateUrl: 'templates/about.html',
        link: function (scope, element) {
            aboutService.getAboutContent()
                .then(function (results) {
                    scope.aboutList = results.aboutContent.listItems;
                }, function (error) {
                    console.log('controller error', error);
                });
        }
    }
}

HTML代码:

<div class="col-md-12 aboutUs-ph padT10 content-ph_abt" ng-repeat="content in aboutList">
    <div class="col-md-2 form-group" ng-if="content.image">
        <img src="{{content.image}}" class="img-responsive" />
    </div>
    <div class="col-md-9">
        <span class="guidedTourText"><b>{{content.title}}</b></span>
        <br>
        <span>{{content.description}}</span>
    </div>
</div>

问题:

在上面的HTML中,您可以在col-md-12中看到col-md-2和col-md-9,假设我有三个div元素,如果内容存在,其中三个元素占据4、4、4。假设最后一个div中没有内容,那么剩下的两个div应该取6,6,反之亦然。我们希望这能从指令中得到实施。

如果我不清楚,请告诉我。

我会在链接函数中设置一个$watch。$watch将监视一个函数,该函数将查找DOM更改(即DIV子级更改)。根据DOM的状态,然后动态添加col-*属性

指令

app.directive('bootstrapColumns', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attr) {
            if (!element.hasClass('row'))
                element.addClass('row');

            scope.$watch(function() {
                var elems = element[0].childNodes;
                var count =0;
                angular.forEach(elems, function(e) {
                    if (e.tagName == 'DIV' && angular.element(e).text() != '')
                        ++count;
                });
                return count;
            },
            function(cols) {
                var colNum = 12 / cols;
                var cssClass = 'col-xs-' + colNum;
                var elems = element[0].childNodes;
                angular.forEach(elems, function(e) {
                    if (e.tagName == 'DIV') {
                        var div = angular.element(e);                  
                        if (div.text() != '' && !div.hasClass(cssClass))
                            div.addClass(cssClass);
                    }
                });
            });
        }
    }
});

HTML

<div bootstrap-columns>
   <div>Column1</div>
   <div>Column2</div>  
</div>

演示Fiddle

我给你一个通用用法,你可以很容易地用你的内容来编写它。假设您的作用域中有三个可用变量:contentcontent2content3。现在你可以这样写:

<div class="row">
    <div class="col-md-6" ng-class="{'col-md-4': content3}">{{content1}}</div>
    <div class="col-md-6" ng-class="{'col-md-4': content3}">{{content2}}</div>
    <div class="col-md-4" ng-show="content3">{{content3}}</div>
</div>

所以这里发生的是,默认情况下,col-md-6将被赋予列,如果第三列中有内容,那么我们也将类col-md-4,这样所有三列都可以平分。col-md-4将优先于col-md-6

或者,如果你想要更多的许可,你也可以简单地写下:

<div class="row">
    <div ng-class="{'col-md-4': content3, 'col-md-6': !content3}">{{content1}}</div>
    <div ng-class="{'col-md-4': content3, 'col-md-6': !content3}">{{content2}}</div>
    <div class="col-md-4" ng-show="content3">{{content3}}</div>
</div>

作为使用ng-class的后续操作,您还可以使用返回类的函数:

var app = angular.module('app', []);
app.directive('aboutDirective', function renderAboutContent(aboutService) {
  return {
    restrict: 'AE',
    scope: {},
    templateUrl: 'about.html',
    link: function(scope, element) {
      aboutService.getAboutContent()
        .then(function(results) {
          scope.aboutList = results.aboutContent.listItems;
        }, function(error) {
          console.log('controller error', error);
        });
      scope.colWidth = function(content) {
        return content.image && content.something ? 'col-xs-4' : 'col-xs-6';
      }
    }
  }
});
app.factory('aboutService', function($timeout) {
  return {
    getAboutContent: function() {
      return $timeout(function() {
        return {
          aboutContent: {
            listItems: [{
              image: 'image1',
              title: 'title1',
              description: 'desc1',
              something: 'something1'
            }, {
              image: 'image2',
              title: 'title2',
              description: 'desc2'
            }, {
              title: 'title3',
              description: 'desc3',
              something: 'something3'
            }]
          }
        };
      }, 1000);
    }
  };
});
.row {
  display: flex;
  text-align: center;
  color: #fff;
}
.image {
  background-color: #75b5aa;
  border: 1px solid #000;
}
.middle {
  background-color: #aa759f;
  border: 1px solid #000;
}
.something {
  background-color: #6a9fb5;
  border: 1px solid #000;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css">
<div class="container" ng-app='app'>
  <about-directive></about-directive>
  
  <script type="text/ng-template" id="about.html">
    <div class="row" ng-repeat="content in aboutList">
      <div ng-if="content.image" class="image" ng-class="colWidth(content)">
        {{ content.image }}
      </div>
      <div class="middle" ng-class="colWidth(content)">
        <span><b>{{content.title}}</b></span>
        <br>
        <span>{{content.description}}</span>
      </div>
      <div ng-if="content.something" class="something" ng-class="colWidth(content)">
        {{content.something}}
      </div>
    </div>
  </script>
</div>