首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在AngularJs指令与ngRepeat相结合后有条件地插入HTML?

如何在AngularJs指令与ngRepeat相结合后有条件地插入HTML?
EN

Stack Overflow用户
提问于 2013-07-09 00:52:48
回答 2查看 2.8K关注 0票数 1

=================

首先我只想说,我对AngularJs的这一业务(今天早些时候开始)很陌生,而且我可能过于复杂了。

既然这么说了,我们就谈正事吧,好吗?

我有下面的jsFiddle,html输出如下。

代码语言:javascript
复制
<div ng-app="test" ng-controller="About" class="hex-grid clearfix ng-scope">
    <div class="hex odd" ng-repeat="person in ledning">
        <a href="">
           <div class="inner">
               <h3 class="ng-binding">Just a name</h3>
               <hr class="grid-1 center">
               <p class="ng-binding">a title</p>
           </div>
           <div class="hex-1">
               <span class="after"></span>
           </div>
           <div class="hex-2">
               <span class="after"></span>
           </div>
           <span class="after"></span>
        </a>
    </div>
   <!-- and 5 times more -->
</div>

,,我想要实现的是-->http://jsfiddle.net/engstrumpan/yCv79/4/embedded/result/

这只是简单的html (没有AngularJs),只是为了演示我想要实现的目标。这个特殊的布局是通过在3和5之后插入3来实现的。

想象一下,如果我想要这样的布局

代码语言:javascript
复制
 1 1 1                1
1 1 1 1   or even    1 1
 1 1 1              1 1 1
                   1 1 1 1
                    1 1 1
                     1 1
                      1

人们将如何着手实现这一目标?这个指令被多次使用,所以我希望它尽可能通用。

到目前为止,我尝试的是如下所示

代码语言:javascript
复制
var app = angular.module('test', []);
app.controller('About', function ($scope) {
    $scope.ledning = [
      {
        ...
        shouldBreak: true
      }
});
app.directive('hexagon', function () {
    var tmpl = '<div>
                   <!-- directive template snippet -->
                </div>
                <br ng-show="{{data.shouldBreak}}" />';

  // rest  of code
});

这个<br ng-show="{{data.shouldBreak}}" />无法工作,因为AngularJs会抛出以下消息Template must have exactly one root element.的异常

还会像这样在指令上干扰compile,但这只会导致在最后一次迭代之后(在中继器完成工作之后)插入<br />

代码语言:javascript
复制
var app = angular.module('test', []);
app.directive('hexagon', function () {
   return { 
     ...
     compile: function($scope, el, attrs){
        return function ($scope, el, attrs){
            if($scope.data.shouldBreak !== undefined){
                el.after('<br />');
            }
        };
     }
    }
});

当涉及到指令时,我已经阅读了文档,要么我只是愚蠢,要么我错过了显而易见的东西,所以请帮帮我。

最后一页,也许睡一觉就可以了。可以这么说,明天就跳回马上去。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-24 21:25:23

所以在离开几天后,我设法找到了一个解决办法,然后当我回到城里时,我又解决了我的问题。

解决方案

视图

代码语言:javascript
复制
<hexagon ng-repeat="person in ledning" data="person" layout="layout"></hexagon>

控制器:

代码语言:javascript
复制
var app = angular.module('test', []);
app.controller('About', function ($scope) {
    ...
    $scope.layout = [2,4]; // what index (inside ngRepeat) should we break on

}

});

和指令

代码语言:javascript
复制
app.directive('hexagon', function ($timeout) {
...
return {
    ...
    scope: {
        data: '=',
        layout: '=' // grab the data bound to 'layout'
    },
    link: function ($scope, el, attrs) {
        $timeout(function(){
            for (var i = 0; i < $scope.layout.length; i++) {

                        if ($scope.layout[i] == $scope.$parent.$index)
                            el.after('<br />');
                    }
        }, 0);
    }
};

});

在这里可以看到一个有用的例子,http://jsfiddle.net/engstrumpan/yCv79/5/

因此,例如,如果我要处理10个项,可以将$scope.layout = [2,6]设置为在此jsFiddle中获得以下输出

我是怎么得到这个解决方案的?我要感谢这个家伙(洛伦兹鱼)和他的博客。至少当使用$timeout使浏览器有足够的时间为元素呈现DOM时,我才能插入<br />

--它可能不是最优雅的解决方案,但在这个特定的场景中,适用于我

票数 2
EN

Stack Overflow用户

发布于 2013-07-09 03:41:31

您可以使用伪类在:before之前或在所讨论的元素:after之后插入一个回车返回:after(尽管如果您支持旧版浏览器,这并不适合您)。

CSS:

代码语言:javascript
复制
.last:before {
    content: "\A";
    white-space:pre;
} 

和一个条件ng-class来设置破行类,其中item.lineBreak包含truefalse,这取决于它在组中的顺序:

代码语言:javascript
复制
ng-class="{last:item.lineBreak}"

这是基本答案,元素上带有ng类的这是工作的敲击

叉子ng-class放在模板中的根元素上。同样的结果。

。。

。。

--棘手/有趣的部分--能够动态地将该类/伪类插入正确的元素中,而无需硬编码它们。看起来你想要一个金字塔(Fibonacci )设计(这就是这个问题看起来很有趣的地方)。

我所做的是使用一个非常基本的循环过程将true属性(从上面的示例item.lineBreak)插入到ng-repeat中的第1、3、6、10和on项中。我把它放在一个选择框模型的$watch中,这样您就可以选择组中的项目数。

这是$watch和

代码语言:javascript
复制
var findFib = function(index){

if(index==increment){
  rowLength += 1;
  increment = rowLength + increment;
  return true;
}   

return false;
}

$scope.$watch('collectionAmount.value', function(val){
    $scope.collection = [];
    rowLength = 1;
    increment = 1;
    var i = 1;

    //loop through the items, using the Fibonacci-like
    //method to determine which items will recieve the 
    //lineBreak property of true;
    while(i<=val){
      var f = findFib(i);
      $scope.collection.push({number: i, lineBreak: f});
      console.log($scope.collection[i-1]);
      i++;      
    }
    //reverse the array if using :before pseudoclass to get upside-down pyramid:
    $scope.collection.reverse();
  })

从那里开始,ng-class有条件地应用了包含插入返回的:before伪类的.last类。这可以很容易地缩放,以适应您更复杂的标记。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17538259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档