在Angular中删除动态创建的Popover

时间:2016-07-05 01:48:13

标签: javascript angularjs twitter-bootstrap

我是角色的新手,我已经能够使用以下功能在所选文本周围创建一个自举弹出窗口

 $scope.highlight = function () {

        var a = document.createElement("a");
        a.setAttribute('tabindex', "0");
        a.setAttribute('data-toggle','popover');
        a.setAttribute("id","1");
        a.setAttribute('data-content',"<button type='button' class='btn btn-default' ng-click='deleteLabel()'><small><span class='glyphicon glyphicon-remove'></span></small></button>");
        a.setAttribute('data-html','True');

        if (window.getSelection) {
                var sel = window.getSelection()
                var range = sel.getRangeAt(0).cloneRange();
                range.surroundContents(a);
                sel.removeAllRanges();
                sel.addRange(range);
        }

        $timeout(function(){
          $('[data-toggle="popover"]').popover();
        }, 50);
    };

并且,在上面的代码中,我创建了一个带有按钮的popover,当点击它(ng-click='deleteLabel()')时应该调用以下函数来删除元素

 $scope.deleteLabel= function(){
            alert("removing label");
            var labelEl=document.getElementById("1");
            labelEl.remove();
        };

但是,单击弹出框中的按钮时,似乎甚至没有调用deleteLabel()。我是如何在popover中调用此函数的?

3 个答案:

答案 0 :(得分:2)

使用ngBootbox这是一种更加Angular的方式;请参阅working plunkr。一般来说,你想要像人们在jQuery中那样避免DOM操作;这是Angular的优势之一就是隐藏了这种复杂性&#34;从你和使用像ngBootbox这样的指令是要走的路。如果您想使用jQuery库,请查找Angular包装器。

如果我理解你的要求,我有两个弹出窗口...一个用于添加元素,另一个用于确认删除元素。

var app = angular.module('plunker', ['ngBootbox']);

app.controller('MainCtrl', ['$scope', '$ngBootbox', function($scope, $ngBootbox) {
  var vm = this;

  vm.name = 'World';
  vm.categories = ['Category 1', 'Category 2'];

  vm.prompt = function() {

    $ngBootbox.prompt('Enter a new category?')
      .then(function(result) {
        console.log('Prompt returned: ' + result);
        vm.categories.push(result);
      }, function() {
        console.log('Prompt dismissed!');
      });

  }

  vm.delete = function(index) {
    console.log('delete index=' + index + ' v=' + vm.categories[index]);
    $ngBootbox.confirm('Are you sure you want to delete ' + vm.categories[index] + ' ?')
      .then(function(result) {
        // Remove element
        vm.categories.splice(index, 1);
      }, function() {
        // Do nothing
        console.log('Prompt dismissed!');
      });
  }
}]);

要添加我调用一个可以输入类别的提示,一旦确认我将其添加到类别数组中,它会自动添加到页面中。

删除者使用ng-repeat的$ index来知道要删除哪个元素,如果用户确认删除,我使用splice将其从数组中删除,并且由于Angular绑定,页面会自动更新。

和HTML:

<body ng-controller="MainCtrl as vm">
  <p>Hello {{vm.name}} !</p>
  <ul>
    <li ng-repeat="c in vm.categories">{{c}} <a href="" ng-click="vm.delete($index)">Delete</a></li>
  </ul>
  <a href="" ng-click="vm.prompt()">Add Category</a> 
</body>

ngBootbox Bootbox.js的AngularJS包装器。 Bootbox.js允许您轻松利用Twitter Bootstrap模式进行javascript警报,确认和提示。 ngBootbox包含三个指令,分别用于alert,confirm和prompt。

Bootbox.js是一个小型JavaScript库,允许您使用Bootstrap模式创建编程对话框,而无需担心创建,管理或删除任何所需的DOM元素或JS事件处理程序。这是最简单的例子:

另外,由于你是角色的新手,我使用控制器作为语法,vm = this以避免$ scope问题;这是一篇文章:AngularJS's Controller As and the vm Variable

答案 1 :(得分:0)

这不是正确的做法。您应该通过directive进行DOM操作或使用bootstrap UI

等库

在您的实现中,通过createElement创建的DOM元素没有绑定。

答案 2 :(得分:0)

这是一个working plunker using the popover.用户选择文本的一部分并单击高亮显示...然后使用您的代码创建一个链接,当按下删除按钮时它会调用删除功能。创建元素后,我调用ng-click工作:

  $compile(a)($scope);

我显示内容并使用'mycontent'标记div作为用于删除所选文本的ID:

<body ng-controller="MainCtrl as vm">
  <p id='mycontent'>{{ vm.content }}</p>
  <button ng-click="vm.highlight()">Highlight</button>


  <script type="text/ng-template" id="tpl.html">
    <div class="popover-content">
      <div>
        <div>
          <span>{{link.title}}</span>
        </div>
        <div>
          <button ng-click='vm.delete()'>Delete</button>
        </div>
      </div>
    </div>
  </script>
</body>

我的应用程序基于您的代码:

var app = angular.module('plunker', ['ui.bootstrap']);

app.controller('MainCtrl', function($scope, $compile, $timeout) {
  var vm = this;
  vm.window = window;

  vm.content = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum';

  vm.delete = function() {
    console.log('delete' + vm.selectedText);
    var d = document.getElementById('mycontent');

    var olddiv = document.getElementById('todelete');

    d.removeChild(olddiv);
  };

  vm.highlight = function() {

    var a = document.createElement("a");

    a.setAttribute('id', 'todelete');
    a.setAttribute('uib-popover', '');
    a.setAttribute('popover-trigger', 'click');
    a.setAttribute('popover-placement', 'top');
    a.setAttribute('ng-click', "info()");
    a.setAttribute('data-html', 'True');
    a.setAttribute('data-content', 'Some content');
    a.setAttribute('uib-popover-template', "'tpl.html'");


    $compile(a)($scope);

    if (window.getSelection) {
      var sel = window.getSelection()
      var text = "";
      if (window.getSelection) {
        text = window.getSelection().toString();
      } else if (document.selection && document.selection.type != "Control") {
        text = document.selection.createRange().text;
      }
      vm.selectedText = text;
      var range = sel.getRangeAt(0).cloneRange();
      range.surroundContents(a);
      sel.removeAllRanges();
      sel.addRange(range);
    }

  };

  vm.getSelectionText = function() {
    var text = "";
    if (window.getSelection) {
      text = window.getSelection().toString();
    } else if (document.selection && document.selection.type != "Control") {
      text = document.selection.createRange().text;
    }
    return text;
  };

});