与特定类型的通用指令(UI组件继承)(A general directive with a spec

2019-08-21 09:07发布

我工作的一个项目,以渲染HTML采取特殊的XML作为输入。 我已经成功的基本情况。 例如:

<mybutton name="layla"></mybutton>

被转换为

<div class="btn">Layla</div>

使用像一个指令

.directive('mybutton', function() {
    return {
        restrict: 'E',
        scope: {
            name: '@'
        },
        templateUrl: 'uicomponents/uiButton.html'
    }
})

真正的XML输入我会收到如下:

<ui type="back_button" x="10.0" y="630.0"/>

我想,以避免更改XML语法,但它可以在需要时进行。 所有的屏幕组件中<ui></ui>标记。 该type属性定义的组件。

你会怎么写这样的标签指令? 它似乎没有智能创建一个巨大指令<ui>的元件和内部具有长开关情况下的属性。

Answer 1:

你可以创建一个转换基于该类型属性的元素,然后重新编译元素的UI指令 - 是这样的:

app.directive('ui',function($compile){
  return {
    restrict:'E',
    compile:function(tElement,tAttrs){
      if(tAttrs.type){
        tElement.attr(tAttrs.type,'');
        tElement.removeAttr('type');
        return function(scope,el){
          $compile(el)(scope);
        }
      }

    }  
  }
});


app.directive('backButton',function(){
  return {
    replace:true,
    template:'<button ng-click="btnClick()">A back-button template</button>'
  }
});

编辑:在我原来的例子,我做编译模板元素的错误 - 如果在ngRepeat所使用的指令,这是不行的。 解决方法是简单的,编译链接元素来代替。 我已经更新了代码和例子。

看看这个plnkr例子 。



Answer 2:

我不知道的创建必将对属性值的指令的一种方式,但也许你可以看看这个以前的SO回答: 自定义输入类型

我们的想法是根据使用该指令的编译功能属性的值来创建不同的模板。 你可以把缓存中所有的自定义输入模板开头(不是必要的)。

angular.module('myapp', ['myapp.directives'])
    .run(['$http', '$templateCache', function($http, $templateCache) {
        $templateCache.put('span.html', '<span>text</span>');
        $http.get('back_button.html', {cache:$templateCache});
    }]);

并根据类型属性从缓存中检索输入模板:

angular.module('myapp.directives', [])
    .directive('ui', ['$templateCache', function($templateCache) {
        return {
            restrict: 'E',
            compile: function(elem, attrs)
            {
                var type = attrs.type || 'span.html'; // default value ?
                elem.replaceWith($templateCache.get(type));
            }
        }
    }]);

此代码是未经测试。

编辑:这也可以工作,我认为,使用带有$链接功能编译,不预压模板,但仍缓存它们:

angular.module('myapp.directives', [])
    .directive('ui', ['$http', '$templateCache', '$compile', function($http, $templateCache, $compile) {
        return {
            restrict: 'E',
            link: function(scope, elem, attrs)
            {
                var type = attrs.type || 'span.html'; // default value ?
                $http.get('views/' + type + '.html', {cache: $templateCache}).then(function(result) {
                    elem.replaceWith($compile(result.data)(scope));
                });
            }
        }
    }]);

此代码为我工作。



文章来源: A general directive with a specific type (UI components inheritance)