1

我希望這對某個人來說很容易,因爲這會讓我瘋狂。親身體驗這個問題:plnkr.coAngularJS的ngBindHtmlUnsafe塊單擊事件(或一些奇怪的事情)

我想從控制器提供一些HTML到視圖。這裏的控制器,它是從Twitter Bootstrap例子中提供禮貌適應:

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

function DropdownCtrl($scope) { 
    $scope.items = [ 
     "The first choice!", 
     "And another choice for you.", 
     "but wait! A third!" 
    ]; 

    $scope.html = '<li class="dropdown" ng-controller="DropdownCtrl">' + 
        '<a class="dropdown-toggle">' + 
         'Click me for a dropdown, yo!' + 
        '</a>' + 
        '<ul class="dropdown-menu">' + 
         '<li><a>Why</a></li>' + 
         '<li><a>doesn\'t</a></li>' + 
         '<li><a>this</a></li>' + 
         '<li><a>work???</a></li>' + 
        '</ul>' + 
        '</li>'; 
} 

沒有什麼令人興奮的,當然。這裏是觀點:

<h3>This works fine</h3> 
<li class="dropdown" ng-controller="DropdownCtrl"> 
    <a class="dropdown-toggle"> 
    Click me for a dropdown, yo! 
    </a> 
    <ul class="dropdown-menu"> 
    <li ng-repeat="choice in items"> 
     <a>{{choice}}</a> 
    </li> 
    </ul> 
</li> 
<h3>Why doesn't this work?</h3> 
<div ng-controller="DropdownCtrl" ng-bind-html-unsafe="html"></div> 

簡而言之,第一個下拉菜單正常工作,根據提供的示例。然而,第二個下拉菜單什麼都不做。它的代碼從控制器傳遞到視圖並完整傳遞,但下拉不會下降。

告訴我有人遇到this problem之前。

+0

我的猜測是,角度「感知」它需要處理該注入有該字符串,它只是假設它是一些HTML。我認爲你可能需要使用一個指令,而不是定義一個模板,以便角度正確處理它,但只是一個猜測。 – shaunhusain

+0

這就是我首先發現問題的方法。我試圖從指令從控制器傳遞到視圖的HTML。這些指令按照自己的意圖工作,但只要您將它們綁定到ngBindHtmlUnsafe的元素,它們就會中斷。我甚至無法在指令定義本身中綁定點擊事件。就好像包含元素阻塞事件一樣。 –

+0

對不起,如果這聽起來很可笑,但說話角度一般。目前,您正在使用內置指令來嘗試注入角度需要處理的代碼。不過,我相信這個指令的目的只是爲了在頁面中注入一些非角度的HTML。相反,如果您使用angular.module(「myModule」,[])。directive(「myDirective」,function()...並在自定義指令中定義了您自己的指令,則將您的html作爲模板屬性,然後使用 – shaunhusain

回答

2

你可以創建一個「編譯」指令,這將需要你的HTML(不管來源)和$編譯它。所以你的觀點將只需要:

<div compile="html"></div> 

這將添加html到頁面而不是顯示它(如ng-bind-html)。它會查找和評估html中的所有指令和表達式。最後但並非最不重要的是,它將鏈接示波器,以便您仍然可以訪問控制器。

這裏是我從AngularJs API Docs中獲得的示例compile指令。它使用$ watch,以便在html更改時繼續編譯。

.directive('compile', function($compile) { 
    return function(scope, element, attrs) { 
    scope.$watch(
     function(scope) { 
      // watch the 'compile' expression for changes 
      return scope.$eval(attrs.compile); 
     }, 
     function(value) { 
      // when the 'compile' expression changes 
      // assign it into the current DOM 
      element.html(value); 

      // compile the new DOM and link it to the current scope. 
      $compile(element.contents())(scope); 
     } 
    ); 
    }; 
}) 

當然爲了簡潔這裏的目的,並且是plunkr

+0

您對原始問題的解決方案:http://plnkr.co/edit/pqo0YDJyWGrSIbEx5zDz?p=preview –

0

您正在將$scope.html定義爲一個字符串,這意味着angular將不會評估其中的任何內容,甚至不會將其視爲它的範圍內。爲了得到角度來評估它加載它通過一個部分。這可以通過在路線,指令或服務中定義模板來完成。它也可以通過包括它來完成。正如我在plunkr

+0

在控制器中定義的字符串正在返回並正確編譯在Plunker HTML中查看源代碼沒有明顯的原因爲什麼提供不應該工作。如果字符串是問題,則只會看到未處理的HTML(如果將其中一個添加到視圖中,會發生什麼情況:{{html}})。 –