2013-12-19 55 views
1

我有一个应用程序,我需要创建html并将其添加到对象数组。这个html应该被输出到页面中。够简单。但是,我还需要使html响应用户操作(点击),在这种情况下,angular需要我使用$ compile来创建角化模板。

查看Plunkr。在这个例子中,应该发生的事情是,当你点击其中一个按钮时,将会在对象中嵌入html代码生成一个弹出窗口,您可以在JSON输出中看到该代码。

只要我这样做,我得到的错误转换为JSON循环结构。如果我不这样做,则不会调用ng-click =“Go()”。

SCRIPT

 var template = "<ul class='unstyled'>" + 
       "<li ng-click='go()' style='background-color:lightcyan;'><ul class='inline'><li>1...</li><li>1...</li></ul></li>" + 
       "<li ng-click='go()'><ul class='inline'><li>1...</li><li>1...</li></ul></li>" + 
       "<li ng-click='go()' style='background-color:lightcyan;'><ul class='inline'><li>1...</li><li>1...</li></ul></li>" + 
       "</ul>"; 

     // template = $compile(template)($scope); 

     $scope.data = [ 
      {"id": 1, "html": template}, 
      {"id": 2, "html": template} 
     ]; 

     $scope.go = function() { 
      alert('It works'); 
     }; 

     $scope.openPopin = function (html) { 
      var e = window.event; 
      var popin = document.getElementById('popin'); 
      var innerdiv = document.getElementById('innerdiv').innerHTML=html; 
      popin.style.top= e.pageY - 20+"px"; 
      popin.style.left = e.pageX - 20+"px"; 
      popin.style.marginLeft = -500+"px"; 
      popin.style.marginTop = -100+"px"; 
     }; 

     $scope.closePopin = function() { 
      var popin = document.getElementById('popin'); 
      popin.style.top = -500+"px"; 
      popin.style.left = -500+"px"; 
     }; 

HTML

<div class="popin grey-border" id="popin"> 
     <button class="close" ng-click="closePopin()">&times;</button> 
     <div id="innerdiv"></div> 
    </div> 

    <pre>{{ data |json }} </pre> 

    <br/> 
    <table style="float: right;"> 
     <tr ng-repeat="d in data" id="{{$index}}"> 
      <td>{{ d.id }} - 
       <button class="btn btn-mini btn-info" ng-click="openPopin(d.html)"><i class="icon-info-sign"></i></button> 
      </td> 
     </tr> 
    </table> 
+0

如果我尝试一下plunker,我会得到一个不同的错误:'错误:e是undefined'。 (使用FF 26)可能是一个跨浏览器兼容性问题。 – towr

回答

2

我把它通过移动编译步骤的openPopin功能,并具有多棱角更换样式属性更改工作(对我来说)替代。而且我也忽略了window.event这是不是跨浏览器兼容(而不是问题的一部分)。

app.controller('MainCtrl', function($scope, $compile) { 
    var template = "<ul class='unstyled'>" + 
      "<li ng-click='go()' style='background-color:lightcyan;'><ul class='inline'><li>1...</li><li>1...</li></ul></li>" + 
      "<li ng-click='go()'><ul class='inline'><li>1...</li><li>1...</li></ul></li>" + 
      "<li ng-click='go()' style='background-color:lightcyan;'><ul class='inline'><li>1...</li><li>1...</li></ul></li>" + 
      "</ul>"; 

    $scope.data = [ 
     {"id": 1, "html": template}, 
     {"id": 2, "html": template} 
    ]; 

    $scope.go = function() { 
     console.log("go"); 
    }; 

    $scope.openPopin = function (html) { 
     var popin = document.getElementById('popin'); 
     var innerdiv = document.getElementById('innerdiv'); 
     innerdiv.innerHTML=html; 
     $compile(innerdiv)($scope); 
     angular.element(popin).css({top:'20px', left:'20px'}); 
    }; 

    $scope.closePopin = function() { 
     var popin = document.getElementById('popin'); 
     angular.element(popin).css({top:'-500px', left:'-500px'}) 
    }; 
}); 

所以,这是让它工作的一种方法。但问题是,你真的想做什么,我们不能以更有角度的方式去做? (使用指令,模板等工具的角度提供。)

+0

感谢您的支持 - 尽管如此,仍然无法实现。我最初使用一个指令来构建这个东西,但是有很多问题,我决定简化它。基本上我有一个从服务器交付的比赛事件列表。竞争对手应该输入他们的个人最好成绩(PB)。然而,数据库中已经有一些个人最好的东西,他们应该能够从中选择。该数据与事件对象一起保存。所以,他们点击一个事件,然后点击弹出窗口列表中的一个PB。弹出窗口关闭,PB被复制到事件数据。 –

+0

我用另一种方法制作了一个jsfiddle:http://jsfiddle.net/W96bb/它使用一个范围属性绑定到popin来确定何时显示它,并使用'ng-repeat'来填充popin。 – towr

+0

这是一个不错的方法。我已经有了另一个指令,并在下面添加了它。对我来说,解决方案是直接编译innerdiv,而不是直接在你的答案中提到的html,这就是我能够使指令工作的原因。非常感谢您的帮助。我在下面添加了我的代码。 –

0

感谢TOWR对你有所帮助 - 见上面

HTML最后一个注释

<script type="text/ng-template" id="cmpbpopin.html"> 
    <button class="btn btn-mini btn-info"><i class="icon-info-sign"></i></button> 
    <div class="popin grey-border"> 
     <button class="close-button">&times;</button> 
     <div></div> 
    </div> 
</script> 

<table style="float: right;"> 
    <tr ng-repeat="d in data" id="{{$index}}"> 
    <td>{{ d.id }}</td> 
    <td> 
     <div cm-pb-popup="d.html"></div> 
    </td> 
</tr> 
</table> 
</body> 

SCRIPT

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

    app.controller('Ctrl', function ($scope, $compile, $http) { 

     var template = "<table class='pblist table table-condensed table-hover'>" + 
       "<tr ng-click='go()'><td>1...</td><td>1...</td></tr>" + 
       "<tr ng-click='go()'><td>1...</td><td>1...</td></tr>" + 
       "<tr ng-click='go()'><td>1...</td><td>1...</td></tr>" + 
       "</table>"; 

     $scope.data = [ 
      {"id": 1, "html": template}, 
      {"id": 2, "html": template} 
     ]; 

    }); 

    app.directive("cmPbPopup", function ($compile, $timeout) { 
     return{ 
      templateUrl: "cmpbpopin.html", 
      scope: { 
       cmPbPopup: "=" 
      }, 
      link: function (scope, elem, attrs) { 
       elem.bind("click", function (e) { 
        var popupDiv = elem.find('div'); 
        var innerDiv = popupDiv.find('div'); 
        var closeButton = popupDiv.find('.close-button') 

        if (e.srcElement.nodeName != 'DIV') { 
         if (e.srcElement.className == 'close-button') { 
          closePopup(); 
         } else if(e.srcElement.nodeName == 'TR' || e.srcElement.nodeName == 'TD'){ 
          // set values in scope 
          closePopup(); 
         } 
         else { 
          innerDiv.html(scope.cmPbPopup); 
          $compile(innerDiv)(scope); 
          popupDiv.css({ 
             'top': e.pageY - e.offsetY + 20, 
             'left': e.pageX - e.offsetX -10, 
             'height': 100, 
             'width': 500, 
             'marginLeft': -500}); 
          $timeout(function(){ 
           closeButton.css('display', 'block'); 
          },500); 
         } 
        } 

        function closePopup(){ 
         popupDiv.css({ 
          'height': 0, 
          'width': 0, 
          'marginLeft': 0}); 
         $timeout(function(){ 
          popupDiv.css({ 
           'top': -500, 
           'left': -500 
          }); 
         },500); 
        } 
       }); 
      } 
     } 
    }) 

CSS

div.popin { 
     position: absolute; 
     width: 0; 
     height: 0; 
     top: -500px; 
     left: -500px; 
     background-color: #ffffff; 
     transition: width 0.5s, height 0.5s, margin-left 0.5s; 
     -webkit-transition: width 0.5s, height 0.5s, margin-left 0.5s; /* Safari */ 
     overflow: hidden; 
    } 

    div.popin div { 
     position: absolute; 
     top: 0 !important; 
     left: 500px !important; 
     width: 470px !important; 
     transition: width 0.2s, height 0.2s, margin-left 0.2s; 
     -webkit-transition: width 0.2s, height 0.2s, margin-left 0.2s; 
    } 

    .close-button{ 
     width: 20px; 
     height: 20px; 
     float: right; 
     font-size: 20px; 
     font-weight: bold; 
     line-height: 20px; 
     color: #000000; 
     text-shadow: 0 1px 0 #ffffff; 
     opacity: 0.2; 
     filter: alpha(opacity=20); 
    } 

    .pblist{ 
     margin-left: 10px !important; 
     margin-top: 10px; 
     width: 470px; 
     float: left; 
    } 

    .grey-border { 
     border: 1px #d3d3d3 solid; 
     -webkit-border-radius: 4px; 
     -moz-border-radius: 4px; 
     border-radius: 4px; 
     padding: 3px; 
    } 
相关问题