将整个元素包含到指令模板中

时间:2019-08-26 00:54:57

标签: javascript angularjs angularjs-directive angularjs-ng-transclude

我正在使用AngularJS指令将元素转换为“包装器”。这是一个示例来说明我的意思:

以下是Material.io复选框的原始html

<div class="checkbox">
    <input type="checkbox" class="native-control" />
    <div class="background">
        <svg class="checkmark" viewBox="0 0 24 24">
            <path class="checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59"/>
        </svg>
        <div class="mixedmark"></div>
    </div>
</div>

每当我想要一个复选框时,都必须复制粘贴很多额外的标记。因此,显而易见的解决方案(如果您使用的是AngularJS)是将其设置为指令(或任何其他前端框架中的等效项)。

我不认为您将其作为组件或元素指令。相反,我看到您会将指令放在<input>元素本身上。这样,a)<input>元素将保留在适当的范围内(不在指令的范围内),b)您不必处理<input>元素具有的所有属性。

最简单的想法如下:

angular.module('test').directive('materialCheckbox', function() {
    const directive = {
        restrict: 'A',
        transclude: 'element', // transcluding the entire element
        template: `
        <div class="checkbox">
            <!-- this is where the <input> tag goes -->
            <ng-transclude></ng-transclude>
            <div class="background">
                <svg class="checkmark" viewBox="0 0 24 24">
                    <path class="checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59"/>
                </svg>
                <div class="mixedmark"></div>
            </div>
        </div>
        `
    };
    return directive;
});

并按如下方式使用:

<input
    material-checkbox
    type="checkbox"
    class="native-control"
    ng-model="vm.propertyForCheckbox"
/>
<!-- obviously you would further optimize this to get rid of type="checkbox" and class="native-control" -->

但是,这不起作用。我试过修改指令的链接函数以直接处理包含关系,但这都不起作用:

// not my actual code - just an example so you understand what I meant by the above sentence
function link(scope, element, attrs, controller, transclude) {
    transclude((clone, cloneScope) => {
        element.append(clone);
    });
}

我的想法为什么有两个方面:

  1. 因为<input>没有结束标记(即不是<input></input>),所以包含过程会中断。但是我(令我非常恼火)尝试在输入元素上放置一个结束标记,但仍然没有骰子。
  2. 由于<input>标签不包含任何子元素,因此AngularJS包含函数决定它不需要覆盖并忽略整个元素(即使我设置了transclude: 'element')。但是,它对此进行的测试也不起作用(即更加不合常规:<input>test</input>

到目前为止,我还无法对此做出解决。有谁知道如何使它工作?

0 个答案:

没有答案