AngularJS: How to implement a directive that outputs its markup?

主宰稳场 提交于 2020-01-15 10:29:13

问题


DEMO

Imagine I have some markup, e.g.:

<my-input model="data.firstName"></my-input>

Now, I would like to create a my-markup directive that will add a button to show/hide its markup.

So, this:

<div my-markup>
  <my-input model="data.firstName"></my-input>
</div>

should result in this:

and when the button is clicked, the markup should appear:

The my-markup directive should not break any data bindings of its children.

Here is my attempt to implement this.

The markup appears, but the button doesn't work. Any ideas how to fix this?

PLAYGROUND HERE


回答1:


Here is my approach. Couple of things:-

1) Instead of isolated scope on myMarkup, create a child scope, ultimately the actual directive myInput will be isolated. This would be required if you do need to support multiple myMarkup directive under the same scope.

2) You need a click event on the button, i wouldn't do logic on the markup instead abstract out to a method on the scope.

3) You would just need one button, do not need 2 buttons. Just change the text of the button.

.directive('myMarkup', function($compile) {


  return {
    restrict: 'A',
    scope: true, //Create a child scope
    compile: function(element) {
      //Just need one button
      var showButton = '<button  ng-click="toggleMarkup()">{{model.showMarkup ? "Hide": "Show"}} Markup</button>';
      var markup = '<pre ng-show="model.showMarkup">' + escapeHtml(element.html()) + '</pre>';

      //append the markups
      element.append(showButton).append(markup);

      return linker;
     }
   };

    function linker(scope, element) {
        scope.model = {
          showMarkup: false
        };
        //Click event handler on the button to toggle markup
        scope.toggleMarkup = function(){
          scope.model.showMarkup = !scope.model.showMarkup;
        }
    };
});

Demo




回答2:


Please see below

function escapeHtml(html) {
  return html.replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

angular.module('App', []).controller('AppCtrl', function($scope) {
  $scope.data = {
    firstName: 'David'
  };
}).directive('myInput', function() {
  return {
    restrict: 'E',
    scope: {
      model: '='
    },
    template: '<input class="my-input" type="text" ng-model="model">'
  };
}).directive('myMarkup', function() {
  return {
    restrict: 'A',
    scope: {},
    link: function(scope, elem, attr) {

    },
    compile: function(element) {
      var showButton = '<button ng-if="data.showMarkup" ng-click="data.showMarkup=!data.showMarkup">Hide Markup</button>';
      var hideButton = '<button ng-if="!data.showMarkup" ng-click="data.showMarkup=!data.showMarkup">Show Markup</button>';
      var markup = '<pre ng-if="data.showMarkup">' + escapeHtml(element.html()) + '</pre>';

      element.append(showButton);
      element.append(hideButton);
      element.append(markup);

      return function(scope, element) {
        scope.data = {
          showMarkup: true
        };
      };
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="App" ng-controller="AppCtrl">
  <pre>data = {{ data | json }}</pre>
  <div my-markup>
    <my-input model="data.firstName"></my-input>
  </div>
</body>


来源:https://stackoverflow.com/questions/26289210/angularjs-how-to-implement-a-directive-that-outputs-its-markup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!