AngularJS:递归树样式

时间:2014-06-14 15:19:14

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

顾名思义我正在尝试构建一个递归树指令,我必须模仿expression builder的结构,因为它是如何设置的,我想用角度组件替换它。我已经看过论坛上的其他帖子,但我的不完全相同。

fiddle感谢朱利安向我展示了如何修复它。

基于表达式构建器的模型具有类似于字段内的条件对象的结构,然后是表达式数组,然后是另一个将被称为嵌套表达式的数组,但基本上将包含一个条件对象,这可以嵌套为深因为它想去。

无论如何所以我创建了一个指令来为表达式构建器中的每个条目创建一个列表条目(ng-repeat)然后我创建了一个链接函数来找出它在最后一个循环中的时间,然后重复每个项目的循环在嵌套表达式数组中(必须有更好的方法)。

它适用于嵌套但现在我想在每个根级别ul分配一个按钮,以便您向另一个数组添加一个新条目(表达式),但是当我尝试它时似乎复制数组然后附加新的值。

其他任务是: 和一个根级别按钮,以便您可以添加第二个嵌套表达式数组(即,同一级别的两个ul),根级别删除,以便您可以删除整个ul嵌套和删除每个li,以便您只能删除一个表达式。

我会保持小提琴,但也许有人可以解决它,然后才能让小提琴工作。

非常感谢任何帮助

此致

angular.module("expressionBuilderApp", [])
.controller('ExpressionBuilderController', ['$scope', function($scope) {  
    $scope.conditions = {
                operator : "and",
                expressions : [
                    {
                        name : "moo"
                    },
                    {
                        name : "mooest"
                    },
                    {
                        name : "mooster"
                    }
                ],
                nestedexpressions : [   
                    {       
                        operator : "or",
                        expressions : [
                            {
                                name : "bow wow"
                            },
                            {
                                name : "woof woof"
                            }
                        ],
                        nestedexpressions : [
                            {
                                operator : "or",
                                expressions : [
                                    {
                                        name : "meow"
                                    },
                                    {
                                        name : "meeew"
                                    }
                                ],
                                nestedexpressions : [
                                    {
                                        operator : "And",
                                        expressions : [
                                            {
                                                name : "oink"
                                            },
                                            {
                                                name : "squeel"
                                            }
                                        ],
                                        nestedexpressions :
                                        [

                                        ]
                                    },
                                    {
                                        operator : "Or",
                                        expressions : [
                                            {
                                                name : "hoot hoot"
                                            },
                                            {
                                                name : "stares with yellow eyes"
                                            }
                                        ],
                                        nestedexpressions :
                                        [

                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]               
        };
 }])
.directive('expressionBuilder', function(){
    return  {
        restrict: 'E',
        template : '<ul><button ng-click="addNewCondition(conditions.expressions)">add</button><li nested-expressions="" conditions="conditions.nestedexpressions" ng-repeat="expression in conditions.expressions" >{{expression.name}}</li></ul>',
        replace: true,
        scope: {conditions: "="},
        controller: function($scope){
            $scope.addNewCondition = function(arrayToPushInto){
                var newCondition = {name: "testing"};
                arrayToPushInto.push(newCondition);
            }
        }
    }
})
.directive('nestedExpressions', function($compile) {
  return {  
        restrict: 'A',
        replace: true,
        link: function(scope, element, attrs){  
            if (scope.$last){
                var conditions = scope.conditions;
                console.log(conditions) ;           
                if(conditions.nestedexpressions.length > 0){
                    element.after($compile('<li ng-repeat="nestedexpression in conditions.nestedexpressions"><expression-builder conditions="nestedexpression"></expression-builder></li>')(scope));
                }
            }
        }
    }
});

1 个答案:

答案 0 :(得分:0)

我不知道为什么说实话,但是我的代码是this所以非常感谢伙伴。无论你是谁。

Ng-include似乎只是使用传入的数组的范围,并且不通过指令嵌套复制函数,请参阅[fiddle](http://jsfiddle.net/cerebral86/g62KP/5/

希望这有助于其他人。

<script type="text/ng-template"  id="conditionExpressionBuilder.html">
    <div>
    <div>
        <button ng-click="addNestedCondition(conditions.nestedexpressions)">Add ()</button>
        <button ng-click="addNewCondition(conditions.expressions)">Add node</button>
    </div>
    <div>
        <select>
            <option ng-selected="{{conditions.operator == operator.value}}" ng-repeat="operator in operators" value="{{operator.value}}">{{operator.display}}</option>
        </select>
    </div>
    <div>
        <ul>
            <li ng-repeat="expression in conditions.expressions">
                <div>
                    <span>
                        <button ng-click="delete(expression, conditions.expressions)" ng-disabled="$first">Delete Item</button>
                    </span>
                    <span>
                        <select>
                            <option ng-selected="{{filterfield.value == expression.filterField}}" ng-repeat="filterfield in filterfields" value="{{filterfield.value}}">{{filterfield.display}}</option>
                        </select>
                    </span>
                    <span>
                        <select>
                            <option ng-selected="{{comparator.value == expression.comparator}}" ng-repeat="comparator in comparators" value="{{comparator.value}}">{{comparator.display}}</option>
                        </select>
                    </span>
                    <span><input type="text" value="{{expression.expressionValue}}" /></span>
                </div>
            </li>
            <li ng-repeat="conditions in conditions.nestedexpressions" ng-if="conditions.expressions.length > 0">
                <button ng-click="removeNestedCondition($index, $parent.$parent.conditions.nestedexpressions)">Remove ()</button>
                <ng-include src="'conditionExpressionBuilder.html'"></ng-include>
            </li>
        </ul>
    </div>
</div>
</script>

angular.module("expressionBuilderApp", [])
.controller('expressionBuilderController', ['$scope', function($scope) {  
         $scope.operators = [
            {
                display: "And",
                value: "and"
            },
            {
                display: "Or",
                value: "or"
            }
        ];
        $scope.filterFields = [
                  {
                      display: "Code",
                      value: "code"
                  },
                  {
                      display: "Capital",
                      value: "capital"
                  },
                  {
                      display: "Government",
                      value: "government"
                  },
                  {
                      display: "Population",
                      value: "population"
                  }
        ];
        $scope.comparators = [
                {
                    display: "contains",
                    value: "contains"
                },
                {
                    display: "Starts With",
                    value: "startswith"
                },
                {
                    display: "Ends With",
                    value: "endswith"
                },
                {
                    display: "Doest not Contain",
                    value: "doesnotcontain"
                }
        ];
        $scope.conditions = {
            operator: "and",
            expressions: [
                {
                    filterField: "code",
                    comparator: "contains",
                    expressionValue: "moo"
                },
                {
                    filterField: "capital",
                    comparator: "startswith",
                    expressionValue: "mooest"
                },
                {
                    filterField: "government",
                    comparator: "endswith",
                    expressionValue: "mooster"
                }
            ],
            nestedexpressions: [
                {
                    operator: "or",
                    expressions: [
                        {
                            filterField: "code",
                            comparator: "endswith",
                            expressionValue: "bow wow"
                        },
                        {
                            filterField: "government",
                            comparator: "doesnotcontain",
                            expressionValue: "woof woof"
                        }
                    ],
                    nestedexpressions: [
                        {
                            operator: "or",
                            expressions: [
                                {
                                    filterField: "code",
                                    comparator: "contains",
                                    expressionValue: "meow"
                                },
                                {
                                    filterField: "code",
                                    comparator: "contains",
                                    expressionValue: "meeew"
                                }
                            ],
                            nestedexpressions: [
                                {
                                    operator: "And",
                                    expressions: [
                                        {
                                            filterField: "government",
                                            comparator: "doesnotcontain",
                                            expressionValue: "oink"
                                        },
                                        {
                                            filterField: "code",
                                            comparator: "endswith",
                                            expressionValue: "squeel"
                                        }
                                    ],
                                    nestedexpressions:
                                    [

                                    ]
                                },
                                {
                                    operator: "Or",
                                    expressions: [
                                        {
                                            filterField: "code",
                                            comparator: "doesnotcontain",
                                            expressionValue: "hoot hoot"
                                        },
                                        {
                                            filterField: "code",
                                            comparator: "contains",
                                            expressionValue: "stares with yellow eyes"
                                        }
                                    ],
                                    nestedexpressions:
                                    [

                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        };
 }])
.directive('conditionExpressionBuilder', function () {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'conditionExpressionBuilder.html',
        scope: {
            conditions: "=",
            operators: "=",
            filterfields: "=",
            comparators: "="
        },
        controller: function($scope)
        {
             $scope.addNewCondition = function (arrayToPushInto) {
                var newCondition = { name: "testing" };
                arrayToPushInto.push(newCondition);
            };
            $scope.delete = function (expressionItem, expressionArray) {
                var index = expressionArray.indexOf(expressionItem);
                expressionArray.splice(index, 1);
            };
            $scope.removeNestedCondition = function (index, nestedExpressionArray) {
                nestedExpressionArray.splice(index, 1);     
            };
            $scope.addNestedCondition = function (nestedExpressionsArray) {
                var nestedConidtion = { operator: "", expressions: [{}], nestedexpressions: [{}] };
                nestedExpressionsArray.push(nestedConidtion);
            };
        }
    }
});