Angular:嵌套指令中传递的参数是状态"未定义"

时间:2017-01-18 20:13:37

标签: angularjs angularjs-directive angularjs-scope

我们正在关注http://mfauveau.github.io/angular-query-builder/中的示例并对其进行修改以符合我们的要求。

我们有一个模态视图(.jsp),它集成了指令(命名为' querybuilder',图片中的黄色部分 - 一个js文件)。控制器(命名为' addEditRuleSetCtrl')和指令包含在上层,包含似乎很好。

我们已从视图(.jsp文件)中启动指令:

<div ng-init="addEditRuleSetCtrl.initSelectors()">
            <query-builder group="addEditRuleSetCtrl.filter.group"
                           rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
                           rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
                           fields="addEditRuleSetCtrl.getCorrespondingFields()"
                           ></query-builder>
</div>

我们已将视图/ .jsp中的指令模板包括在内(请注意,在创建新组时,此指令会再次在此处启动):

<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
    <div class="form-inline">
        <select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
        <button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
        <button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
        <button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
    </div>
    <div class="group-conditions">
        <div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
            <div ng-switch="rule.hasOwnProperty('group')">
                <div ng-switch-when="true">
                        <query-builder group="rule.group"
                                       rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
                                       rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
                                       fields="addEditRuleSetCtrl.getCorrespondingFields()"
                        ></query-builder>
                </div>
                <div ng-switch-default="ng-switch-default">
                    <div class="form-inline">
                        <select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
                        <select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
                        <input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
                        <button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

我们的问题是:树/组的第一层具有所有参数(字段,规则条件集运算符,规则条件运算符)的正确值。因此,在第一层中,所有相关的下拉列表都显示了正确的值。但是当我点击按钮&#34;添加组&#34;在第一层,所有的参数现在都是&#34;未定义&#34;因此,从第二层开始的所有下拉列表都是空的(由图中的红色箭头标记显示)

问题是:

  1. 从组的第2层开始是正确的吗? params超出了控制器的范围,因为它们已被定义 在视图块之外?
  2. 如何让小组的所有层都可以使用参数?
  3. 以下是视图(.jsp文件):

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    
    <link 
        href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
        rel="stylesheet">
    </link>
    
    <%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
    
    <form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
    
        <div class="modal-content">
    
            <div class="modal-header">
                <h4 class="modal-title">
                    {{addEditRuleSetCtrl.windowHeader}}
                    <button type="button" class="btn btn-danger btn-sm pull-right"
                            ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
                        <span class="glyphicon glyphicon-remove-sign"></span>
                    </button>
                </h4>
            </div>
    
            <div class="modal-body">
                Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
                <br />
                Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
                Output: {{ addEditRuleSetCtrl.output }}
    
                <div class="alert alert-info">
                    <strong>Example Output</strong><br>
                    Output: {{ addEditRuleSetCtrl.output }}
                </div>
    
                <div ng-init="addEditRuleSetCtrl.initSelectors()">
                    <query-builder group="addEditRuleSetCtrl.filter.group"
                                   rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
                                   rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
                                   fields="addEditRuleSetCtrl.getCorrespondingFields()"
                                   ></query-builder>
                </div>
    
            </div>
    
            <div class="modal-footer">
                <button type="button"  class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
            </div>
    
        </div>
    
    </form>
    
    <script type="text/ng-template" id="/queryBuilderDirective.html">
        <div class="alert alert-warning alert-group">
            <div class="form-inline">
                <select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
                <button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
                <button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
                <button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
            </div>
            <div class="group-conditions">
                <div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
                    <div ng-switch="rule.hasOwnProperty('group')">
                        <div ng-switch-when="true">
                                <query-builder group="rule.group"
                                               rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
                                               rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
                                               fields="addEditRuleSetCtrl.getCorrespondingFields()"
                                ></query-builder>
                        </div>
                        <div ng-switch-default="ng-switch-default">
                            <div class="form-inline">
                                <select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
                                <select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
                                <input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
                                <button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </script>
    

    指令(.js文件):

    AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
        return {
            restrict: 'E',
            scope: {
                group: '=',
                ruleConditionOperators: '=',
                ruleConditionSetOperators: '=',
                fields: '='
    
            },
    
            templateUrl: '/queryBuilderDirective.html',
            compile: function (element, attrs) {
                var content, directive;
                content = element.contents().remove();
                return function (scope, element, attrs) {
    
    
                    scope.addCondition = function () {
    
                        window.alert("[addCondition] : " + "group : " + JSON.stringify( scope.group) + "...BREAK..."
                                                 +"fields : " + JSON.stringify( scope.ruleConditionOperators) + "...BREAK..."
                                                 +"Condition : "+JSON.stringify(scope.ruleConditionOperators) + "...BREAK..."
                                                 +"Condition set: "+JSON.stringify(scope.ruleConditionSetOperators));
                        scope.group.rules.push({
                            condition: '=',
                            field: 'Firstname',
                            data: ''
                        });
                    };
    
                    scope.removeCondition = function (index) {
                        scope.group.rules.splice(index, 1);
                    };
    
                    scope.addGroup = function () {
    
                        window.alert("[addGroup] :"  + "group : " + JSON.stringify( scope.group) + "...BREAK..."
                            +" fields : " + JSON.stringify( scope.fields) + "...BREAK..."
                            +"Condition : "+JSON.stringify(scope.ruleConditionOperators) + "...BREAK..."
                            +"Condition set: "+JSON.stringify(scope.ruleConditionSetOperators));
    
                        scope.group.rules.push({
                            group: {
                                operator: 'AND',
                                rules: []
                            }
                        });
                    };
    
                    scope.removeGroup = function () {
                        "group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
                    };
    
                    directive || (directive = $compile(content));
    
                    element.append(directive(scope, function ($compile) {
                        return $compile;
                    }));
                }
            }
        }
    }]);
    

    控制器:

    AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField','FileService',
        function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField, FileService )
            {
                var self = this;
                self.origin = origin;
                self.iceField = iceField;
    
                self.data = '{"group": {"operator": "AND","rules": []}}';
                self.output = 'bologna';
    
                self.fieldsDDE = [
                    { name: 'FirstnameDDE' },
                    { name: 'LastnameDDE' },
                    { name: 'BirthdateDDE' },
                    { name: 'CityDDE' },
                    { name: 'CountryDDE' }
                ];
    
                self.fieldsATT = [
                    { name: 'FirstnameATT' },
                    { name: 'LastnameATT' },
                    { name: 'BirthdateATT' },
                    { name: 'CityATT' },
                    { name: 'CountryATT' }
                ];
    
                self.ruleConditionSetOperators = [
                ];
    
                self.ruleConditionOperators = [
                               ];
    
                self.filter = JSON.parse(self.data);
    
                self.initSelectors  = function()
                {
                    self.getRuleConditionOperators();
                    self.getRuleConditionSetOperators();
                }
    
                self.getRuleConditionOperators = function()
                {
                   if ( self.ruleConditionOperators.length == 0 )
                    {
    
                         RuleEngineService.getAllRuleConditionOperators()
                             .then(
                                 function( d )
                                 {
                                    self.ruleConditionOperators = d;
                                 },
                                 function( errResponse )
                                 {
                                 console.error( 'Error while fetching rule-condition-operators' );
                                 }
                             );
                    }
                    return self.ruleConditionOperators;
    
                };
    
                self.getRuleConditionSetOperators = function()
                {
                    if ( self.ruleConditionSetOperators.length == 0 )
                    {
    
                        RuleEngineService.getAllRuleConditionSetOperators()
                            .then(
                                function( d )
                                {
                                    self.ruleConditionSetOperators = d;
                                },
                                function( errResponse )
                                {
                                    console.error( 'Error while fetching rule-condition-operators' );
                                }
                            );
                    }
                    return self.ruleConditionSetOperators;
    
                };
    
    
                self.htmlEntities = function(str)
                {
                    return String(str).replace(/</g, '&lt;').replace(/>/g, '&gt;');
                };
    
    
                self.displayErrorMessages = false;
                self.createSuccess = '';
                self.createHeader = '';
                self.backendErr = "";
    
                self.windowHeader = "Create/Edit Rule Group";
    
    
                self.close = function()
                {
                    $uibModalInstance.close();
                };
    
                self.getCorrespondingFields = function()
                {
                   // window.alert("---------------Reached client side controller to getCorrespondingFields");
                    return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
                };
    
                self.computed = function(group)
                {
                    window.alert("Inside controller: computed");
    
                    if (!group) return "";
                    for (var str = "(", i = 0; i < group.rules.length; i++) {
                        i > 0 && (str += " <strong>" + group.operator + "</strong> ");
                        str += group.rules[i].group ?
                            self.computed(group.rules[i].group) :
                            group.rules[i].field + " " +
                            //htmlEntities(group.rules[i].condition)
                            group.rules[i].condition
                            + " " + group.rules[i].data;
                    }
    
                    return str + ")";
                };
    
    
                $scope.$watch('filter', function (newValue)
                {
                    self.output = self.computed(newValue);
                }, true);
    
                self.test = function()
                {
                    window.alert(JSON.stringify( self.filter) );
                };
    
            } 
        ]);
    

    截图:

    enter image description here

    我可以在这里得到任何帮助吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

这是我的解决方法(将此添加到指令中),这有助于:

class Data:
    """Mixin class"""
    data = [42]

class Foo(Data):
    """Mixin class"""
    def do_foo_to_data(self):
        # call a dozen functions that do complicated stuff to data

class Bar(Data):
    """Mixin class"""
    def do_bar_to_data(self):
        # call other functions that do different stuff to data

class Baz(Foo, Baz):
    pass

所以,该指令现在看起来像:

scope.fieldCodes = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;