AngularJS - 如何更改包含数据绑定的模板中的元素?

时间:2014-06-19 05:10:26

标签: javascript angularjs angularjs-directive

在模板中使用动态标记名称的Angular建议方法是什么?

我有一个包含h1-h6标签的下拉列表。用户可以选择其中任何一个,并且内容将更改为由所选标头标记(存储在$ scope中)进行包装。内容绑定到模型,即{{}}内。

要保持绑定,我可以更改标记并使用$ compile。但是,这不起作用,因为它会在Angular用模型值替换{{}}之前(显然)附加。这是页面加载时的h3。

示例:

<div id="root">
    <h3 id="elementToReplace">{{ modelData }}</h3>
</div>

重新编译时,我尝试使用如下字符串:

<{{ tag }} id="elementToReplace">{{ modelData }}</{{ tag }}>

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

Demo Plunker Here

定义名为&#39; tag&#39;的范围变量并将其绑定到您的选择列表和自定义指令。

HTML:

     <select ng-model="tag" ng-init="tag='H1'">
           <option ng-value="H1">H1</option>
           <option ng-value="H2">H2</option>
           <option ng-value="H3">H3</option>
           <option ng-value="H4">H4</option>
           <option ng-value="H5">H5</option>
     </select> 
     <tag tag-name="tag">Hey There</tag>

接下来,使用双向模型绑定将标记范围模型传递到指令中:

  var app = angular.module('app',[]);
  app.directive('tag', function($interpolate) {
      return  {
         restrict: 'E',
         scope: {
             tagName: '='
         },
         link: function($scope, $element, $attr) {
            var content = $element.html();
            $scope.$watch('tagName', function(newVal) {
                 $element.contents().remove();
                 var tag = $interpolate('<{{tagName}}>{{content}}</{{tagName}}>')
                       ({tagName: $scope.tagName, content: content});
                 var e = angular.element(tag);
                 $element.append(e);
            });
         }
      }
  });

请注意,在custom指令中,我们使用$ interpolate服务根据在选择列表中选择的Tag生成HTML元素。 $ watch函数用于监视标记模型的更改,当它更改时,新元素将附加到DOM。

答案 1 :(得分:0)

这是我敲了一个,即使你说你不想要它;)

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="../lib/jquery.js"></script>
    <script src="../lib/angular.js"></script>

    <script>
        var app = angular.module('app', []);
        app.controller('ctrl', ['$scope', function ($scope) {
            $scope.modelData = "<h1>Model Data</h1>" +
                    "<p id='replace'>This is the text inside the changing tags!</p>";
            $scope.tags = ["h1", "h2", "h3", "h4", "p"];
            $scope.selectedTag = "p";
        }]);

        app.directive("tagSelector", function(){
            return {
                resrict: 'A',
                scope: {
                    modelData: '@',
                    selectedTag: '@'
                },
                link: function(scope, el, attrs){

                    scope.$watch("selectedTag", updateText);
                    el.prepend(scope.modelData);

                    function updateText(){
                        var tagStart = "<" + scope.selectedTag + " id='replace'>";
                        var tagEnd = "</" + scope.selectedTag + ">";
                        $("#replace").replaceWith(tagStart + $("#replace").html() + tagEnd);
                    }
                }
            }
        });

    </script>

</head>
<body ng-app="app">
<div ng-controller="ctrl">
    <select ng-model="selectedTag" ng-options="tag for tag in tags"></select>
    <div tag-selector selected-tag="{{selectedTag}}" model-data="{{modelData}}"></div>
</div>
</body>
</html>

答案 2 :(得分:0)

更多犹太洁食版。适用于ng-repeat和嵌套指令。 工作示例here

angular.module('myApp', [])
  .directive('tag', function($interpolate, $compile) {
    return {
      priority: 500,
      restrict: 'AE',
      terminal: true,
      scope: {
        tagName: '='
      },
      link: function($scope, $element) {
        $scope.$on('$destroy', function(){
          $scope.$destroy();
          $element.empty();
        });
        $scope.$parent.$watch($scope.tagName, function(value) {
          $compile($element.contents())($scope.$parent, function(compiled) {
            $element.contents().detach();

            var tagName = value || 'div';

            var root = angular.element(
              $element[0].outerHTML
              .replace(/^<\w+/, '<' + tagName)
              .replace(/\w+>$/, tagName + '>'));
            root.append(compiled);
            $element.replaceWith(root);
            $element = root;
          });
        });
      }
    }
  })
  .controller('MyCtrl', function($scope) {
    $scope.items = [{
      name: 'One',
      tagName: 'a'
    }, {
      name: 'Two',
      tagName: 'span'
    }, {
      name: 'Three',
    }, {
      name: 'Four',
    }];
  });

用途:

  <div ng-app="myApp">
    <div ng-controller="MyCtrl">
      <tag  class="item" tag-name="'item.tagName'" ng-repeat="item in items">
        {{item.name}}
      </tag>
    </div>
  </div>
相关问题