programing

Angular를 작성하려면HTML 콘텐츠가 포함된 JS UI 부트스트랩 팝오버?

madecode 2023. 3. 4. 15:23
반응형

Angular를 작성하려면HTML 콘텐츠가 포함된 JS UI 부트스트랩 팝오버?

예쁜 JSON 오브젝트를 포함한 프리태그를 사용하여 부트스트랩 팝오버를 만들고 싶습니다.순진한 구현,

<span popover='<pre>{[ some_obj | json:"  " ]}</pre>'
      popover-trigger='mouseenter'>

팝업에 삽입하기 전에 내용을 이스케이프합니다.html 콘텐츠로 팝오버 본문을 지정하는 가장 좋은 방법은 무엇입니까?

갱신:

여기서 알 수 있듯이 기본 템플릿을 덮어쓰지 않고 이 작업을 수행할 수 있습니다.

오리지널:

가 1.2+ 1 1.2 상인 경우ng-bind-html-unsafe가 삭제되었습니다.$sce 서비스 참조를 사용해야 합니다.

다음은 신뢰할 수 있는 HTML을 만들기 위한 필터입니다.

MyApp.filter('unsafe', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsHtml(val);
    };
}]);

이 필터를 사용한 덮어쓰기된 Angular Bootstrap 0.11.2 템플릿입니다.

// update popover template for binding unsafe html
angular.module("template/popover/popover.html", []).run(["$templateCache", function ($templateCache) {
    $templateCache.put("template/popover/popover.html",
      "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
      "  <div class=\"arrow\"></div>\n" +
      "\n" +
      "  <div class=\"popover-inner\">\n" +
      "      <h3 class=\"popover-title\" ng-bind-html=\"title | unsafe\" ng-show=\"title\"></h3>\n" +
      "      <div class=\"popover-content\"ng-bind-html=\"content | unsafe\"></div>\n" +
      "  </div>\n" +
      "</div>\n" +
      "");
}]);

편집: 다음은 Plunker 구현입니다.

편집 2: 이 답변은 계속 조회되므로 가능한 한 최신 상태로 유지하겠습니다.참고로 여기에서는 angular-ui 부트스트랩 레포의 템플릿을 보여 줍니다.이것이 변경되면 덮어쓰기 템플릿에 일치하는 업데이트와 추가가 필요합니다.ng-bind-html=\"title | unsafe\" ★★★★★★★★★★★★★★★★★」ng-bind-html=\"content | unsafe\"계속 작업하도록 속성을 지정합니다.

최신 대화에 대해서는, 여기를 참조해 주세요.

popover-template 디렉티브를 사용합니다.

0.13.0 이상의 angular-ui 버전을 사용하는 경우 최적의 옵션은popover-template과 같습니다.사용 방법은 다음과 같습니다.

<button popover-template="'popover.html'">My HTML popover</button>

<script type="text/ng-template" id="popover.html">
    <div>
        Popover content
    </div>
</script>

것을 .popover-template="'popover.html'".

'데모 플런커' 참조


을 html로 할 수 .<script type="text/ng-template>위와 같은 요소.

번째 데모 플런커참조하십시오.

GITHUB 프로젝트에 솔루션을 게재했습니다.https://github.com/angular-ui/bootstrap/issues/520

이 기능을 프로젝트에 추가하고 싶은 경우, 여기 패치가 있습니다.

다음 지시사항을 추가합니다.

angular.module("XXX")
    .directive("popoverHtmlUnsafePopup", function () {
      return {
        restrict: "EA",
        replace: true,
        scope: { title: "@", content: "@", placement: "@", animation: "&", isOpen: "&" },
        templateUrl: "template/popover/popover-html-unsafe-popup.html"
      };
    })

    .directive("popoverHtmlUnsafe", [ "$tooltip", function ($tooltip) {
      return $tooltip("popoverHtmlUnsafe", "popover", "click");
    }]);

템플릿을 추가합니다.

<div class="popover {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">
  <div class="arrow"></div>

  <div class="popover-inner">
      <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>
      <div class="popover-content" bind-html-unsafe="content"></div>
  </div>
</div>

: 사법 usage :<button popover-placement="top" popover-html-unsafe="On the <b>Top!</b>" class="btn btn-default">Top</button>

plunkr : http://plnkr.co/edit/VhYAD04ETQsJ2dY3Uum3?p=preview 에서 확인하실 수 있습니다.

기본 팝오버 템플리트를 변경하여 HTML 콘텐츠를 허용하도록 지정해야 합니다.popover-content div에 되었습니다.content"html" "html" :

 angular.module("template/popover/popover.html", []).run(["$templateCache", function ($templateCache) {
        $templateCache.put("template/popover/popover.html",
            "<div class='popover {{placement}}' ng-class='{ in: isOpen(), fade: animation() }'>" + 
            "<div class='arrow'></div><div class='popover-inner'>" + 
            "<h3 class='popover-title' ng-bind='title' ng-show='title'></h3>" + 
            "<div class='popover-content' ng-bind-html-unsafe='content'></div>" +
            "<button class='btn btn-cancel' ng-click='manualHide()'>Cancel</button>" +
            "<button class='btn btn-apply' ng-click='manualHide()'>Apply</button></div></div>");
    }]);

부트스트랩에 popover다음과 같은 각도 지시어를 사용할 수 있습니다.HTML 템플릿의 잡동사니를 제거하여 사용하기 매우 편리합니다.

팝오버를 설정할 수 있습니다.title,content,placement, 페이드인/아웃delay,trigger이벤트 및 콘텐츠 취급 여부html또, 컨텐츠의 오버플로나 클리핑도 방지합니다.

모든 코드와 관련된 plunker http://plnkr.co/edit/MOqhJi

스크린 캡

imgur

사용.

<!-- HTML -->
<div ng-model="popup.content" popup="popup.options">Some element</div>

/* JavaScript */
this.popup = {
  content: 'Popup content here',
  options: {
    title: null,
    placement: 'right', 
    delay: { show: 800, hide: 100 }
  }
}; 

자바스크립트

/**
 * Popup, a Bootstrap popover wrapper.
 *
 * Usage: 
 *  <div ng-model="model" popup="options"></div>
 * 
 * Remarks: 
 *  To prevent content overflow and clipping, use CSS
 *  .popover { word-wrap: break-word; }
 *  Popup without title and content will not be shown.
 *
 * @param {String}  ngModel           popup content
 * @param {Object}  options           popup options
 * @param {String}  options.title     title
 * @param {Boolean} options.html      content should be treated as html markup
 * @param {String}  options.placement placement (top, bottom, left or right)
 * @param {String}  options.trigger   trigger event, default is hover
 * @param {Object}  options.delay     milliseconds or { show:<ms>, hide:<ms> }
 */
app.directive('popup', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      ngModel: '=',
      options: '=popup'
    },
    link: function(scope, element) {
      scope.$watch('ngModel', function(val) {
        element.attr('data-content', val);
      });

      var options = scope.options || {} ; 

      var title = options.title || null;
      var placement = options.placement || 'right';
      var html = options.html || false;
      var delay = options.delay ? angular.toJson(options.delay) : null;
      var trigger = options.trigger || 'hover';

      element.attr('title', title);
      element.attr('data-placement', placement);
      element.attr('data-html', html);
      element.attr('data-delay', delay);
      element.popover({ trigger: trigger });
    }
  };
});

팝오버를 사용할 수 있는http://https://github.com/jbruni/bootstrap-bower-jbruni, 를 참조해 주세요.

다음의 CSS 스타일링이, 특정의 케이스에서 내가 원하는 것을 실현한 것 같습니다.

.popover-content {
  white-space: pre;
  font-family: monospace;
}

일반적인 문제는 아직 해결되지 않았다.

이하에, 제 솔루션의 요점을 나타냅니다.

  • 액세스 가능(탭 키를 사용하여 활성화/비활성화할 수 있습니다).
  • 사용자가 팝오버를 마우스로 가리키고 팝오버가 열린 상태를 유지할 수 있습니다.
  • 페이지에서 여러 개의 팝오버를 허용하지만, 한 번에 하나의 팝오버만 활성화할 수 있습니다.
  • 부트스트랩 팝오버 스타일은 차용되었지만 서드파티에 의존하지 않습니다.

이 동작방법은 페이지 상에 있는 몇 개의 팝오버를 인스턴스화하는 것입니다.popover어레이(배선 방법에 대해서는 코멘트의 TODO를 참조해 주세요.

그 후 사용자가 팝오버를 트리거하는 요소를 탭 또는 호버할 때마다 해당 팝오버를 활성화합니다.popover사용자가 요소를 더 이상 맴돌지 않을 때 특정 요소에 대해 타임아웃을 설정합니다.popover배열에 있습니다.타임아웃이 경과한 경우 사용자가 요소를 재허브 또는 재포커싱(탭을 통해)했는지 여부를 빠르게 확인합니다.그렇다면 팝오버를 살려두죠그렇지 않으면 팝오버를 숨깁니다.

CSS에서는 부트스트랩을 사용하고 싶지 않았기 때문에 부트스트랩에서 직접 스타일을 빌렸습니다.부트스트랩의 팝오버 스타일을 사용하려고 하면 부트스트랩이 실행되고 있는 경우, 커스텀 팝오버에 독자적인 스크립트가 필요 없는 이상한 동작이 발생할 수 있습니다.

HTML:

 <section>
    <a href="#" 
       ng-mouseover="showPopover(i)" 
       ng-mouseleave="hidePopover(i)"
       ng-focus="showPopover(i)"
       ng-blur="hidePopover(i)">
        I trigger a popover - {{i}}
    </a>
    <popover popover-show="popover[i].popoverTracker">
      <div class="arrow"></div>
      <div class="custom-popover-content"
           ng-mouseover="showPopover(i)" 
           ng-mouseleave="hidePopover(i)"
           ng-focus="showPopover(i)"
           ng-blur="hidePopover(i)">
        <a href="#"
           ng-focus="showPopover(i)"
           ng-blur="hidePopover(i)">You can tab into me, I'm accessible!</a>
        <br/>
        <a href="#" 
           ng-focus="showPopover(i)"
           ng-blur="hidePopover(i)">You can tab into me, I'm accessible!</a>
      </div>
    </popover>
  </section> 

각도 컨트롤러 및 지시:

angular.module('controllers', []);
angular.module('directives', []);
angular.module('myApp', ['ngAnimate', 'controllers', 'directives']);

angular.module('controllers')
    .controller('MainCtrl', function ($scope, $timeout) {

    $scope.popover = [];

    (function init() {
        // TODO: Make this dynamic so that we can pass it a value and it will generate the right amount
        // Initializing the array of popovers on startup
      createPopoverTrackers(20);
        })();

    // Creating an array of popovers equal to the number of popovers on the page
    function createPopoverTrackers(count) {
        for(var i = 0; i < count; i++) {
        $scope.popover.push({
            popoverTracker: false,
          popoverKeepAlive: false,
          timer: null
        })
      }
    }

    // A user has focused on an element that has an associated popover
    $scope.queueOpenPopover = function(index) {
    // Show our specified tracker
    $scope.popover[index].popoverTracker = true;

     // Hide the rest
     Object.keys($scope.popover)
        .filter(function(trackerIndex) {
          return trackerIndex != index
       })
      .forEach(function(trackerIndex) {
          $scope.popover[trackerIndex].popoverTracker = false;
          $scope.popover[trackerIndex].popoverKeepAlive = false;

          const timer = $scope.popover[trackerIndex].timer;
          if(timer) {
             $timeout.cancel(timer);
             $scope.popover[trackerIndex].timer = null;
          }
      })
        };

    // Queuing up the demise of the popover
    $scope.queueKillPopover = function(index) {
      $scope.popover[index].timer = $timeout(function() {
             if (!$scope.popover[index].popoverKeepAlive) {
          // Popover or the popover trigger were not hovered within the time limit, kill it!
          $scope.popover[index].popoverTracker = false;
        }
        }, 700);
    };

    // When a user focuses into the actual popover itself or it's trigger,  we need to keep it alive
    $scope.showPopover = function(index) {
        $scope.popover[index].popoverKeepAlive = true;
      $scope.queueOpenPopover(index);
    };

    // The user has removed focus from the popover or it's trigger, set this to false so the timer knows to kill it
    $scope.hidePopover = function(index) {
        $scope.popover[index].popoverKeepAlive = false;
      $scope.queueKillPopover(index);
    };
});

angular.module('directives')
    .directive('popover', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {
            'popoverShow': '='
        },
        template: '<div class="custom-popover bottom" ng-show="popoverShow" ng-transclude></div>'
    };
});

부트스트랩에서 빌린 CSS:

.custom-popover {
    position: absolute;
    z-index: 1010;
    max-width: 276px;
    padding: 1px;
    text-align: left;
    white-space: normal;
    background-color: #fff;
    border: 1px solid rgba(0,0,0,0.2);
    border-radius: 6px;
    box-shadow: 0 5px 10px rgba(0,0,0,0.2);
    background-clip: padding-box;
}

.custom-popover .arrow,
.custom-popover .arrow:after {
  position: absolute;
  display: block;
  width: 0;
  height: 0;
  border-color: transparent;
  border-style: solid;
}

.custom-popover .arrow {
  border-width: 11px;
}

.custom-popover .arrow:after {
  border-width: 10px;
  content: "";
}

.custom-popover.bottom {
  margin-top: 10px;
}

.custom-popover.bottom .arrow {
  top: -11px;
  left: 50%;
  margin-left: -11px;
  border-bottom-color: rgba(0, 0, 0, 0.25);
  border-top-width: 0;
}

.custom-popover.bottom .arrow:after {
  top: 1px;
  margin-left: -10px;
  border-bottom-color: #ffffff;
  border-top-width: 0;
  content: " ";
}

.custom-popover-content {
  padding: 9px 14px;
}

언급URL : https://stackoverflow.com/questions/16722424/how-do-i-create-an-angularjs-ui-bootstrap-popover-with-html-content

반응형