【问题标题】:ngRepeat doesn't update custom element directivengRepeat 不更新自定义元素指令
【发布时间】:2015-01-28 21:01:28
【问题描述】:

我有一个自定义元素指令 (restrict: "E"),它将自定义元素替换为取决于范围的新元素(通过处理 link)。这工作正常,但ngRepeat 无法删除此类指令。似乎找不到目标 DOM 元素,因为它已被指令本身替换。

代码:

<body ng-app="app">
  <div ng-controller="controller">
    <h3>Click an element to remove it</h3>
    <custom ng-repeat="tag in tags" ng-click="remove(tag)"></custom>
  </div>

  <script>
    angular.module("app", []).controller("controller", function($scope) {
      $scope.tags = [
        { tagName: "button", text: "button" },
        { tagName: "div", text: "div" },
        { tagName: "span", text: "span" }
      ];

      $scope.remove = function(tag) {
        console.log("remove", tag.text);
        $scope.tags.splice($scope.tags.indexOf(tag), 1);
      }
    }).directive("custom", function($compile) {
      return {
        restrict: "E",        
        link: function(scope, element, attr) {
          var tag = angular.element("<" + scope.tag.tagName + ">").text(scope.tag.text);

          tag.attr("ng-click", attr.ngClick)

          $compile(tag)(scope);

          element.replaceWith(tag);
        }
      }
    });
  </script>
</body>

Live demo(尝试单击button,然后单击div - 按钮首先不会消失,然后 div 和按钮都会消失)。如果我使用 element.append(tag) 而不是 element.replaceWith(tag),它会起作用。

这能以某种方式工作吗?我需要该指令具有自定义标签名称,该名称取决于范围,并且在删除项目时也可以与 ngRepeat 一起使用。长话短说,由于我无法控制的 CSS 规则,我不需要 DOM 中的 &lt;custom&gt; 元素。 replace:true 之类的东西可以与 link 一起使用。

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    要回答我自己的问题,是的,如果使用transclude: 'element' 是可能的。然后 angular 为 link 函数提供了一个注释 DOM 元素,该元素稍后用于 DOM 操作。以下是相关代码:

      return {
        restrict: "E",
        transclude: "element",
        link: function(scope, element, attr) {
          var tag = angular.element("<" + scope.tag.tagName + ">").text(scope.tag.text);
    
          tag.attr("ng-click", attr.ngClick)
    
          $compile(tag)(scope);
    
          element.after(tag); // insert after the comment node
        }
    

    还有一个live demo

    【讨论】:

      【解决方案2】:

      为什么需要更换?

       element.append(tag);
      

      好像work ok:

      <!DOCTYPE html>
      <html>
      
        <head>
          <meta charset="utf-8" />
          <title>AngularJS Plunker</title>
          <script>document.write('<base href="' + document.location + '" />');</script>
          <link rel="stylesheet" href="style.css" />
          <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.11/angular.js" data-semver="1.3.11"></script>
          <script src="app.js"></script>
        </head>
      
      <body ng-app="app">
        <div ng-controller="controller">
          <h3>Click an element to remove it</h3>
          <custom ng-repeat="tag in tags" ng-click="remove(tag)"></custom>
          <br><br>{{tags}}  
        </div>
      
        <script>
          angular.module("app", []).controller("controller", function($scope) {
            $scope.tags = [
              { tagName: "button", text: "button" },
              { tagName: "div", text: "div" },
              { tagName: "span", text: "span" }
            ];
      
            $scope.remove = function(tag) {
              console.log("remove", tag.text);
              $scope.tags.splice($scope.tags.indexOf(tag), 1);
            }
          }).directive("custom", function($compile) {
            return {
              restrict: "E",        
              link: function(scope, element, attr) {
                var tag = angular.element("<" + scope.tag.tagName + ">").text(scope.tag.text);
      
                tag.attr("ng-click", attr.ngClick)
      
                $compile(tag)(scope);
      
                element.append(tag);
              }
            }
          });
        </script>
      </body>
      
      </html>
      

      【讨论】:

      • 因为 CSS 规则我无法控制。额外的包装元素打破了某些 CSS 规则(直接后代)。我只是不需要 DOM 中的 &lt;custom&gt; 元素。 replace:true 之类的东西与 link 一起使用
      • 这不应该是一个答案,而是一个评论。 element.append工作的问题中指定的OP
      猜你喜欢
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-26
      • 2016-05-13
      相关资源
      最近更新 更多