2014-06-19 34 views
1

什麼是在模板中使用動態標籤名稱最有角度的推薦方式?AngularJS - 如何更改包含數據綁定的模板中的元素?

我有一個包含h1-h6標籤的下拉列表。用戶可以選擇其中的任何一種,並且內容將更改爲被選定的標題標記(存儲在$ scope中)包裝。內容綁定到模型,即在{{}}中。

要堅持綁定,我可以改變標記並使用$ compile。但是,這不起作用,因爲它在Angular用模型值替換{{}}之前被附加(顯然)。它在頁面加載時爲h3。

例子:

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

當重新編譯我曾嘗試使用字符串如下:

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

任何想法?

+0

我懷疑會最好是去創建一個自定義的指令。因此,而不是使用'{{modelData}}'你會有'

'。這會給你更多的控制權,並且modelData不一定是html。 – david004

+0

嗨大衛,我實際上已經有一個自定義指令,我傳遞我想要的數據。我希望將標記名稱作爲模型的一部分,以便我可以動態地將其顯示在{{tag}}的位置。 –

回答

5

Demo Plunker Here

定義一個名爲「標記」的範圍變量並將其綁定到您的選擇列表和自定義指令兩者。

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); 
      }); 
     } 
     } 
    }); 

注意,在定製指令,我們使用的是$插值服務根據在選擇列表中選擇的標籤生成HTML元素。 $ watch函數用於監視標記模型的更改,當它更改時,新元素將附加到DOM。

+0

謝謝!我會玩這個遊戲。 –

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> 
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> 
相關問題