2013-12-19 54 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; 
    } 
相關問題