Angularjs:select中的递归指令

Angularjs : directive recursive in select

本文关键字:递归 指令 select Angularjs      更新时间:2023-09-26

我的递归指令构建选择输入时遇到问题。

我有一些模块有一些功能,这些功能可以有一些子功能,比如:

[
  0: {
    module_name : administration
    fonctions : [
       {
         fonction_id : 1
         fonction_name : getAdministration
         children : [
            {
              fonction_id : 2
              fonction_name : getParameters
              children : []
            },
            {
              fonction_id : 3
              fonction_name : getModules
              children : []
            },
            ...
         ]
       },
    ]
  },
  1: {
    module_name : Account
    fonctions : [
       {
         fonction_id : 4
         fonction_name : CreateAccount
         children : []
       },
       {
         fonction_id : 5
         fonction_name : EditAccount
         children : []
       },
       ....
    ]
  },
  ...
]

目标是在中构建optgroup为每个模块选择,并将该模块的每个函数放入选项中,如果该函数有子函数,则在相同的上继续否则创建一个新的optgroup以获得此结果:

<select>
  <optgroup label='Administration'>
    <option value='1'>getAdministration</option>
    <option value='2'>getParameters</option>
    <option value='3'>getModules</option>
    ...
  </optgroup>
  <optgroup label='Account'>
    <option value='1'>CreateAccount</option>
    <option value='2'>EditAccount</option>
    ...
  </optgroup>
</select>

为了制定这些指令,我受到了这篇文章的启发:http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/

请参阅我的两个指令:

WcSelectOptionGroup:

angular.module('app.administration').directive('wcSelectOptionGroup', function()
{
    return {
        restrict: 'E',
        replace: true,
        scope: {
            elts: '=',
            selectId: '='
        },
        template: '<select><optgroup' +
                        'label="{{ elt.module_name }}"' +
                        'ng-repeat="elt in elts">' +
                            '<wc-select-option' +
                                'ng-repeat="fnct in elt.fonctions"' +
                                'ng-selected="fnct.fonction_id === selectId"' +
                                'item="fnct"' +
                                'selectId="selectId">' +
                            '</wc-select-option>' +
                  '</optgroup></select>',
        link: function(scope)
        {
            console.log('hello 1!!!!!!!');
        }
    };
});

第二种:

WcSelectOption:

angular.module('app.administration').directive('wcSelectOption', function($compile)
{
    return {
        restrict: 'E',
        replace: true,
        scope: {
            item: '=',
            selectId: '='
        },
        template: '<option' +
                        'value="{{ item.fonction_id }}"' +
                        'ng-selected="item.fonction_id === selectId">' +
                        '{{ item.fonction_title }}' +
                   '</option>',
        link: function(scope, element, attrs)
        {
            console.log('hello 2!!!!!!!');
            angular.forEach(scope.item.children, function(child)
            {
                $compile('<wc-select-option' +
                            'item="child"' +
                            'selectId="selectId">' +
                            '</wc-select-option>')
                (scope, function(cloned, scope)
                {
                    element.append(cloned);
                });
            });
        }
    };
});

和html:

<select
       class="form-control"
       name="parent"
       ng-model="fonction.fonction_parent_id"
       required>
           <option
               value="0"
               ng-selected="fonction.fonction_parent_id === null">
                 Aucun
           </option>
           <optgroup label="{{ $root.getWord('Functions not assigned') }}">
               <option
                   ng-repeat="fnct in fonctions.not_assigned"
                   value="{{ fnct.fonction_id }}"
                   ng-selected="fnct.fonction_id===fonction.fonction_parent_id">
                     {{ fnct.fonction_name }}
               </option>
           </optgroup>
           <wc-select-option-group
               elts="modules"
               selectId="fonction.fonction_parent_id">
           </wc-select-option-group>
</select>

当我运行应用程序时,指令WcSelectOptionGroup不执行,因为当我放入console.log('hello 1!!')时,什么都没有发生。。。我不明白为什么。

因此,如果你有一些想法:)提前感谢

最终我找到了一个解决方案:)

我做了3个指令:WcSelect、WcSelectOptionGroup和WcSelect-Option

参见指令:

WcSelect

angular.module('app.administration').directive('wcSelect', ['$compile', function($compile)
{
    return {
        restrict: 'E',
        replace: true,
        scope: {
            modules: '=',
            fnctsNotAssigned: '=',
            fnctModel : '='
        },
        templateUrl: 'app/_common/directives/wc-select.tpl.html',
        link: function(scope, element, attrs)
        {
            scope.$watch('modules', function(newValue)
            {
                if (angular.isArray(newValue) &&
                    newValue.length > 0)
                {
                    angular.element('.optGrpFunctions').remove();
                    var str = '<wc-select-option-group ng-repeat="module in modules" elt="module" select-id="parentId"></wc-select-option-group>';
                    $compile(str)(scope, function(cloned, scope) { element.append(cloned); });
                }
            });
            scope.$watch('fnctModel', function(newValue)
            {    
                if (newValue.fonction_parent_id !== null)
                {
                    angular.element('.optGrpFunctions').remove();
                    scope.parentId = newValue.fonction_parent_id;
                    if (angular.isArray(scope.modules) &&
                      scope.modules.length > 0)
                    {
                        var str = '<wc-select-option-group ng-repeat="module in modules" elt="module" select-id="parentId"></wc-select-option-group>';
                        $compile(str)(scope, function(cloned, scope) { element.append(cloned); });
                    }
                }
            });
            scope.parentId = null;
        }
    };
}]);

关联的模板:

<select
        class="form-control"
        name="parent"
        ng-model="fnctModel.fonction_parent_id"
        required>
    <option
        value="0"
        ng-selected="fnctModel.fonction_parent_id === null">
            Aucun
    </option>
    <optgroup
        label="{{ $root.getWord('Functions not assigned') }}"
        ng-if="fnctsNotAssigned.length > 0">
        <option
            ng-repeat="fnct in fnctsNotAssigned"
            value="{{ fnct.fonction_id }}"
            ng-selected="fnct.fonction_id === fnctModel.fonction_parent_id">
            {{ fnct.fonction_name }}
        </option>
    </optgroup>
</select>

WcSelectOptionGroup

angular.module('app.administration').directive('wcSelectOptionGroup', ['$compile', function($compile)
{
    return {
        restrict: 'E',
        replace: true,
        scope: {
            elt: '=',
            selectId: '='
        },
        template: '<optgroup class="optGrpFunctions" label="{{ elt.module_name }}"></optgroup>',
        link: function(scope, element, attrs)
        {
            /**
             * ajoute les fonctions de elt a l'optGroup
             *
             * @author tibo
             */
            scope.$watch('elt.fonctions', function(newValue)
            {
                if (angular.isArray(newValue) &&
                   newValue.length > 0)
                {
                    var str = '<wc-select-option ng-repeat="fnct in elt.fonctions" item="fnct" select-id="selectId"></wc-select-option>';
                    $compile(str)(scope, function(cloned, scope) { element.append(cloned); });
                }
            });
        }
    };
}]);

WcSelectOption

angular.module('app.administration').directive('wcSelectOption', ['$compile', function($compile)
{
    return {
        restrict: 'E',
        replace: true,
        scope: {
            item: '=',
            selectId: '='
        },
        template: '<option value="{{ item.fonction_id }}" ng-selected="item.fonction_id === selectId">{{ item.fonction_title }}</option>',
        link: function(scope, element, attrs)
        {
            /**
             * ajoute les fonctions enfants de item a loptgroup
             *
             * @author tibo
             */
            scope.$watch('item.children', function(newValue)
            {
                if (angular.isArray(newValue))
                {
                    var str = '<wc-select-option ng-repeat="child in item.children" item="child" select-id="selectId"></wc-select-option>';
                    $compile(str)(scope, function(cloned, scope){ element.after(cloned); });
                }
            });
        }
    };
}]);

我认为我的错误是将指令直接放在指令的模板中,而不是使用$compile来执行指令WcSelectOptionGroup。

再见:)