dynamically adding directives in ng-repeat

前端 未结 3 1705
北恋
北恋 2020-12-08 05:24

I am trying to dynamically add different directives in an ng-repeat however the output is not being interpreted as directives.

I\'ve added a simple example here: htt

3条回答
  •  伪装坚强ぢ
    2020-12-08 05:45

    I know this is an old question, but google brought me here, and I didn't like the answers here... They seemed really complicated for something that should be simple. So I created this directive:

    ***** NEW CONTENT *****

    I've since made this directive more generic, supporting a parsed (the typical angular value) "attributes" attribute.

    /**
     * Author: Eric Ferreira  ©2016
     *
     * This directive takes an attribute object or string and adds it to the element
     *   before compilation is done. It doesn't remove any attributes, so all
     *   pre-added attributes will remain.
     *
     * @param {Object?} attributes - object of attributes and values
     */
    .directive('attributes', function attributesDirective($compile, $parse) {
        'use strict';
    
        return {
            priority: 999,
            terminal: true,
            restrict: 'A',
            compile: function attributesCompile() {
                return function attributesLink($scope, element, attributes) {
                    function parseAttr(key, value) {
                        function convertToDashes(match) {
                            return match[0] + '-' + match[1].toLowerCase();
                        }
    
                        attributes.$set(key.replace(/([a-z][A-Z])/g, convertToDashes), value !== undefined && value !== null ? value : '');
                    }
    
                    var passedAttributes = $parse(attributes.attributes)($scope);
    
                    if (passedAttributes !== null && passedAttributes !== undefined) {
                        if (typeof passedAttributes === 'object') {
                            for (var subkey in passedAttributes) {
                                parseAttr(subkey, passedAttributes[subkey]);
                            }
                        } else if (typeof passedAttributes === 'string') {
                            parseAttr(passedAttributes, null);
                        }
                    }
    
                    $compile(element, null, 999)($scope);
                };
            }
        };
    });
    

    For the OP's use case, you could do:

  • Or to use it as an attribute directive:

  • ***** END NEW CONTENT ******

    /**
     * Author: Eric Ferreira  ©2015
     *
     * This directive will simply take a string directive name and do a simple compilation.
     * For anything more complex, more work is needed.
     */
    angular.module('attributes', [])
    
    .directive('directive', function($compile, $interpolate) {
        return {
            template: '',
            link: function($scope, element, attributes) {
                element.append($compile('
    ')($scope)); } }; }) ;

    For the specific case in this question, one can just rewrite the directive a bit to make it apply the directive to a span by class, as so:

    angular.module('attributes', [])
    
    .directive('directive', function($compile, $interpolate) {
        return {
            template: '',
            link: function($scope, element, attributes) {
                element.replaceWith($compile('')($scope));
            }
        };
    })
    
    ;
    

    Then you can use this anywhere and select a directive by name dynamically. Use it like so:

  • I purposely kept this directive simple and straightforward. You may (and probably will) have to reword it to fit your needs.

提交回复
热议问题