Implementation of Dynamic html with Custom Instructions in ng repeat Instructions in AngularJs

  • 2021-07-12 05:16:36
  • OfStack

Today, when writing table with angular, I encountered a problem. In ng-repeat, there are dynamic html, and these html contain custom instructions.

Because I want to implement a reusable table, I define an instruction myStandTable, and the instruction code is roughly as follows:


var myCommon = angular.module("myCommon",[]);
myCommon.directive("myStandTable", function () {
 return {
 restrict: "A",
 templateUrl: "app/template/tableTem.html",
 transclude: false,
 replace: true,
 controller: function ($scope,$compile, commonService) {
  // do something... 
 },
 link: function (scope, element, attris) {
 }
 }
});

The code for the tableTem. html file is as follows:


<div>
 <table class="table table-hover table-bordered">
 <thead>
  <tr>
  <th ng-if="tableData.multiSelect">
   <input type="checkbox" id="check-all" ng-model="itemsChecked">
   <label for="check-all" class="fa" ng-class="{'fa-square-o': !itemsChecked, 'fa-check-square-o': itemsChecked }" aria-hidden="true">
   </label>
  </th>
  <th ng-repeat="item in tableData.thead">{{item}}</th>
  </tr>
 </thead>
 <tbody>
  <tr ng-repeat="item in tableData.items" ng-click="selectItem(item)" ng-init="item.selected = false" ng-class="{'selected': item.selected}">
  <td ng-if="tableData.multiSelect">
   <input type="checkbox" id="check_{{$index}}" ng-model="item.selected">
   <label for="check_{{$index}}" class="fa" ng-class="{'fa-square-o': !item.selected, 'fa-check-square-o': item.selected }" aria-hidden="true">
   </label>
  </td>
  <td ng-repeat="name in tableData.theadName">
   {{item[name]}}
   
  </td>
  </tr>
 </tbody>
 </table>
</div>

The controller file code is as follows:


var myBasis = angular.module("myBasis",["myCommon"]);
myBasis.controller("myCtrl", function ($scope) {
 $scope.tableData = {
 multiSelect: false,
 pageSize: [10, 20, 50],
 thead: [" Import time ", " Import name ", " Results ", " Operation "],
 theadName: ["importDate", "name", "result", "oper"]
 };
});

Above, the function of displaying data in the table has been completed, but in the table column, there are often operations on a certain row of data, and these operations also need to be inserted into the table in the form of html, and there will be instructions such as ng-click in these html, or custom instructions. For example: " < a href='javascript:;' ng-click='show(item)' > View information < /a > "; This kind of html, inserted into td, will be shown as html code, and will not be converted into html.

After consulting the method on the Internet, we found a solution to switch to html and added a filter, as follows:


myCommon.filter("trusted", function ($sce) {
 return function (html) {
 if (typeof html == "string") {
  return $sce.trustAsHtml(html);
 }
 return html;
 }
});

Then modify the code in the temp file:


 <td ng-repeat="name in tableData.theadName">
 <span ng-bind-html="item[name] | trusted"></span>
</td>

Through the above method, html can be converted into normal results, but ng-click on a tag has no effect. The key to the problem is that this html has not been compiled by angular, so ng-click does not work and needs to be compiled manually. The modification is as follows:

temp file code modification:


 <td ng-repeat="name in tableData.theadName">
 <div compile-bind-expn = "item[name]">
 </div>
 </td>

When item [name] is equal to "<a href='javascript:;' ng-click='show(item)'> View information < /a > ", we need to manually compile through the compileBindExpn instruction, and then put it into div. The instruction code is as follows:


myCommon.directive("compileBindExpn", function ($compile) {
 return function linkFn(scope, elem, attrs) {
 scope.$watch("::"+attrs.compileBindExpn, function (html) {
  if (html && html.indexOf("<") != -1 && html.indexOf(">") != -1) {
  console.log(1);
  var expnLinker = $compile(html);
  expnLinker(scope, function transclude (clone) {
   elem.empty();
   elem.append(clone);
  });
  } else {
  elem.empty();
  elem.append(html);
  }
 })
 }
});

After this solution, the html code can finally be displayed normally, and the ng-click methods on it can also be used normally. If you have any questions, please leave me a message, and this site will reply to you in time. Thank you very much for your support to this site!


Related articles: