angular指令总是为包装外部元素添加属性

时间:2014-05-28 14:43:18

标签: javascript angularjs angularjs-directive angular-template

我刚开始有角度地将头撞在墙上:

我正在制作一个可重复使用的滑块元素,它将生成一个包含在标签中的输入类型=“范围”。

我希望将指令中定义的属性应用于指令模板中定义的子输入元素,但它们也会添加到包装标签元素中。这看起来很乱,我想我错过了一些基本的东西。

最好的方法是什么?我是否需要使用编译功能,这似乎会破坏在指令中使用模板的目的?

当前的html:

<slider min="0" max="1000" step="1" label="foo" ng-model="slider1" value="750">
</slider>

当前指令:

myApp.directive('slider', function() {
return {
    restrict: 'AE',
    scope:{
        data:'=ngModel',
        min:'@',
        max:'@',
        step:'@',
        label:'@',
        value:'='
    },
    replace: 'true',
    template: '<label>{{label}}<input min="{{min}}" max="{{max}}" step="{{step}}" type="range" ng-model="data" value="{{value}}" />{{data}}</label>'
};

});

当前输出:

<label min="0" max="1000" step="1" label="foo" ng-model="slider1" value="250" class="ng-isolate-scope ng-pristine ng-valid ng-binding">
    foo
    <input min="0" max="1000" step="1" type="range" ng-model="data" value="250" class="ng-pristine ng-valid">
</label>

期望的输出:

<label>
    foo
    <input min="0" max="1000" step="1" type="range" ng-model="data" value="250" class="ng-pristine ng-valid">
</label>

2 个答案:

答案 0 :(得分:0)

这很奇怪。虽然我还没试过,但我猜想替换是将滑块元素的属性添加到模板中第一个元素,即label。尝试在标签之前在模板中添加另一个元素,并尝试使用replace:false执行相同的

<div class="filler></div><label>{{label}}<input min="{{min}}" max="{{max}}" step="{{step}}" type="range" ng-model="data" value="{{value}}" />{{data}}</label>

<强>更新

因为replate:true似乎总是添加属性,你可能必须使用replace:false,并创建一个编译或链接函数,手动删除元素,如

link: function (scope, element, attrs) {    angular.element(element).remove();

答案 1 :(得分:0)

我看到这个问题已经有几个月了,所以你现在可能已经开始了,但我还是想回答它。也许它会帮助其他人。

我现在只使用AngularJS大约3个星期了,但我觉得你得到的凌乱输出是AngularJS的典型特征,毕竟它只是凌乱如果你&#39 ;在生成的html中重新钻研。 AngularJS似乎并不太关心使用标签和属性来污染html - 看起来(至少在我看来),关于制作可重复使用的组件和位,以及在编码时更容易使用它们。

我发现最好不要使用替换因为当你检查你的html时,很难判断你是否刚刚使用了你的指令,或者你是否只是简单地直接输入html在页面中。此外,文档提到它只是真正的用例是在您生成SVG文档时。

让我在这里用你的例子来说明我想说的话:

来源:

<some html />
<slider min="0" max="1000" step="1" label="foo" ng-model="slider1" value="750" />
<some other html />

您想要的结果:

<some html />
<label>
    text
    <input min="0" max="1000" step="1" type="range" ng-model="data" value="250" class="ng-pristine ng-valid" />
</label>
<some other html />

替换结果:

<some html />
<label min="0" max="1000" step="1" label="foo" ng-model="slider1" value="250" class="ng-isolate-scope ng-pristine ng-valid ng-binding">
    text
    <input min="0" max="1000" step="1" type="range" ng-model="data" value="250" class="ng-pristine ng-valid" />
</label>
<some other html />

没有替换的结果:

<some html />
<slider min="0" max="1000" step="1" label="foo" ng-model="slider1" value="250" class="ng-isolate-scope ng-pristine ng-valid ng-binding">
    <label>
        text
        <input min="0" max="1000" step="1" type="range" ng-model="data" value="250" class="ng-pristine ng-valid" />
    </label>
</slider>
<some other html />

我建议当你检查html并看到你想要的结果时,你怎么知道你是否只是在html中写道或是否使用了指令。在没有替换的结果中,指令被明确命名,并且它不可能将其误认为是其他任何东西。插入的html看起来与预期完全一样,没有标签上的其他属性。

当然你可以使用编译函数删除@frank提到的多余元素或属性,但我再次建议这仍然会使你生成的html不如没有替换的结果清晰。

我还要指出,对于这个问题的未来观众,AngularJS指令的替换选项已被弃用,并在文档中注明了这一点:( [DEPRECATED!],​​将在下一个主要版本中删除 - 即v2.0)

请参阅此处的文档:https://docs.angularjs.org/api/ng/service/ $ compile#-replace-deprecated-will-be-removed-in-next-major-release-i-e-v2-0 -