Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 当replace=true时,如何防止角度指令中的属性重复_Angularjs_Angularjs Directive - Fatal编程技术网

Angularjs 当replace=true时,如何防止角度指令中的属性重复

Angularjs 当replace=true时,如何防止角度指令中的属性重复,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我发现指定replace:true的角度指令会将指令用法中的属性复制到模板呈现的输出中。如果模板包含相同的属性,则模板属性值和指令属性值将在最终输出中组合在一起 指令用法: <foo bar="one" baz="two"></foo> 指令: .directive('foo', function() { return { restrict: 'E', replace: true, template: '<div bar="{{ba

我发现指定
replace:true
的角度指令会将指令用法中的属性复制到模板呈现的输出中。如果模板包含相同的属性,则模板属性值和指令属性值将在最终输出中组合在一起

指令用法:

<foo bar="one" baz="two"></foo>

指令:

.directive('foo', function() {
  return {
    restrict: 'E',
    replace: true,
    template: '<div bar="{{bar}}" baz="baz"></div>',
    scope: {
      bar: '@'
    },
    link: function(scope, element, attrs, parentCtrl) {
      scope.bar = scope.bar || 'bar';
    }
  };
})
指令('foo',函数(){ 返回{ 限制:'E', 替换:正确, 模板:“”, 范围:{ 酒吧:“@” }, 链接:函数(作用域、元素、属性、parentCtrl){ scope.bar=scope.bar | |“bar”; } }; }) 输出:

<div bar="one " baz="two baz" class="ng-isolate-scope"></div>

bar=“one”
中的空格和
baz
中的多个值都会导致问题。有没有办法改变这种行为?我意识到我可以在指令中使用非冲突属性,并在输出中同时具有模板属性和非冲突属性。但我希望能够使用相同的属性名称,并更好地控制模板的输出

我想我可以使用
link
方法和
element.removeAttr()
element.attr()
。看起来应该有更好的解决办法

最后,我意识到有人在谈论弃用
remove:true
,但保留它是有正当理由的。在我的例子中,我需要它用于使用转换生成SVG标记的指令。详情请参见此处:

不,没有什么好的声明方式来告诉Angular在移植到模板中时应该如何合并或操作
x
属性

Angular实际上直接将属性从源元素复制到目标元素(除了少数例外),并合并属性值。您可以在Angular编译器的函数中看到这种行为

由于无法更改该行为,因此可以通过指令定义的
compile
link
属性对属性及其值进行控制。对于您来说,在编译阶段而不是链接阶段进行属性操作更有意义,因为您希望在任何链接函数运行时这些属性都“准备就绪”

您可以这样做:

.directive('foo', function() {
  return {
    // ..
    compile: compile
    // ..
  };

  function compile(tElement, tAttrs) {
    // destination element you want to manipulate attrs on
    var destEl = tElement.find(...);

    angular.forEach(tAttrs, function (value, key) {
      manipulateAttr(tElement, destEl, key);
    })

    var postLinkFn = function(scope, element, attrs) {
      // your link function
      // ...
    }

    return postLinkFn;
  }

  function manipulateAttr(src, dest, attrName) {
    // do your manipulation
    // ...
  }
})

了解您希望如何合并这些值会很有帮助。模板优先,元素优先,还是需要某种合并

由于我只能做一个假设,下面的代码假设您希望从元素上存在的模板中删除属性

.directive('foo', function() {
    return {
        restrict: 'E',
        replace: true,
        template: function(element, attrs) {
            var template = '<div bar="{{bar}}" baz="baz"></div>';
            template = angular.element(template);
            Object.keys(attrs.$attr).forEach(function(attr) {\
                // Remove all attributes on the element from the template before returning it.
                template.removeAttr(attrs.$attr[attr]);
            });
            return template;
        },
        scope: {
          bar: '@'
        }
    };
})
指令('foo',函数(){ 返回{ 限制:'E', 替换:正确, 模板:函数(元素、属性){ var模板=“”; 模板=角度元素(模板); Object.key(attrs.$attr).forEach(function(attr){\ //在返回模板之前,从模板中删除元素上的所有属性。 template.removeAttr(attrs.$attr[attr]); }); 返回模板; }, 范围:{ 酒吧:“@” } }; })
这是一个设计冲突
replace
只能与简单的
一起使用,不能使用属性。如果您需要这些属性,应该将它们传递给指令,而不是被替换的元素。@DaveAlperovich您能详细说明一下您的意思吗,任何更深入地描述您的问题的文档或链接?我希望在元素中传递属性,以便可以设置隔离范围,但我不希望输出这些属性。只应输出模板中的属性。我必须使用
replace
,因为我使用的是SVG标记。我希望元素中的属性传递给用于设置隔离范围的指令,但我不希望这些属性包含在输出中。只应输出模板中的属性。谢谢你的解决方案,我想它会有用的!感谢您确认angular没有声明性的方式来做我想做的事情,并分享了一个建议的解决方案。我希望避免使用编译函数,但也许它最适合我的需要。