AngularJS $编译不评估表达式

时间:2014-08-06 15:42:41

标签: angularjs angularjs-directive

我已经坚持了一段时间并需要一些帮助。我正在尝试构建一个标签控件,允许我动态添加带有HTML内容的标签。我找到的选项卡控件使用id元素来引用选项卡的url。什么'我发现我可以使用我的选项卡名称对id进行硬编码,但它可以正常工作,但是如果我使用表达式{{eisEvent.url}},$ compile将不会将其评估为真实姓名。我会把它放在一个小提琴中,但JSFiddle今天遇到了一些重大问题,所以我会粘贴代码。它只有三个文件。

的style.css

ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
 float: left;
 border: 1px solid #000;
 border-bottom-width: 0;
 margin: 3px 3px 0px 3px;
 padding: 5px 5px 0px 5px;
 background-color: #CCC;
 color: #696969;
 }
#mainView {
border: 1px solid black;
clear: both;
padding: 0 1em;
}
.active {
background-color: #FFF;
color: #000;
}

tabs.js

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

myApp.service('EISEventService', function($rootScope) {
   var eisSubscriptions = [];

   this.addSubscription = function( eisEvent ){
      console.log( eisEvent.name + "\n" + eisEvent.message );
      $rootScope.$broadcast( "EVENT_ADDED", eisEvent );
      eisSubscriptions.push( eisEvent );
   };

   this.removeSubscription = function( eisEvent ){
      //TODO Remove the element from the array.
      $rootScope.$broadcast( "EVENT_REMOVED", eisEvent );
   };
});

myApp.controller('TabsCtrl', function ($scope, EISEventService) {
   console.log("Initializing Tab Controller");
   $scope.eisEvent = {};
   $scope.tabs = [{
      title: 'One',
      url: 'one.tpl.html'
   }, {
      title: 'Two',
      url: 'two.tpl.html'
   }];

   $scope.currentTab = 'one.tpl.html';

   $scope.onClickTab = function (tab) {
      $scope.currentTab = tab.url;
   };

   $scope.isActiveTab = function(tabUrl) {
      return tabUrl == $scope.currentTab;
   };

   $scope.$on('EVENT_ADDED', function( event, args ){
      console.log( "EventName : " + event.name );
      var eisEvent = args;
      console.log("EIS Event = " + eisEvent.name  );
      console.log("Message = " + eisEvent.message );
      console.log("URL = " + eisEvent.url );
      $scope.eisEvent = eisEvent;

      $scope.tabs.push( {title : eisEvent.name, url:eisEvent.url });
      // By doing this, it seems to work, but I need the second option to work because I will eventually retrieve this HTML from
      // the server that will need to be parsed.
      // Option 1
      $scope.tabs_html.push( {html: '<script type="text/ng-template" id="'+eisEvent.url+'">Hello Event: '+eisEvent.name+'</script>' });

      // Option 2
      //This doesn't appear to work because of the binding.
      //$scope.tabs_html.push( {html: '<script type="text/ng-template" id="{{eisEvent.url}}">Hello Event: {{eisEvent.url}}</script>' });

      // Option 3
      //If I hard code the ID it will work.  For example if I enter test in the text box on the demo, the code below will work.
      //$scope.tabs_html.push( {html: '<script type="text/ng-template" id="test_url">Hello Event: {{eisEvent.url}}</script>' });
   });
   $scope.tabs_html = [];
});

myApp.controller('AddCtrl', function($scope, EISEventService) {
   $scope.onAddClick = function(){
      console.log("add clicked");
      var eisEvent = { name : $scope.txtName, url: $scope.txtName+"_url", message: "This is a log message"};
      EISEventService.addSubscription(eisEvent);

   }
});
myApp.directive("bindCompiledHtml", function($compile, $timeout) {
   return {
      template: '<div></div>',
      scope: {
         rawHtml: '=bindCompiledHtml'
      },
      link: function(scope, elem, attrs) {
         scope.$watch('rawHtml', function(value) {
            if (!value) return;
            // we want to use the scope OUTSIDE of this directive
            // (which itself is an isolate scope).
            var newElem = $compile(value)(scope.$parent);
            elem.contents().remove();
            elem.append(newElem);
         });
      }
   };
});

最后是tabs.html

<!DOCTYPE html>
<html ng-app="TabsApp">
<head>
    <title></title>
    <link rel="stylesheet" type="text/css" href="style.css">
    <!--<script src="../lib/angular.min.js"></script>-->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
    <script src="tabs.js"></script>

</head>
<body >
<div>
    <div id="add" ng-controller="AddCtrl">
        <input type="text" ng-model="txtName">
        <button ng-click="onAddClick()">Add</button>
    </div>

    <div id="tabs" ng-controller="TabsCtrl">
        <ul>
            <li ng-repeat="tab in tabs"
                ng-class="{active:isActiveTab(tab.url)}"
                ng-click="onClickTab(tab)">{{tab.title}}</li>
        </ul>
        <div id="mainView">
            <div ng-include="currentTab"></div>
        </div>

        <script type="text/ng-template" id="one.tpl.html">
            <div>
                <h1>View One</h1>
                <p>Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc.</p>
            </div>
        </script>

        <script type="text/ng-template" id="two.tpl.html">
            <div>
                <h1>View Two</h1>
                <p>Curabitur vulputate, ligula lacinia scelerisque tempor, lacus lacus ornare ante, ac egestas est urna sit amet arcu. Class aptent taciti sociosqu.</p>
            </div>
        </script>

        <script type="text/ng-template" id="three.tpl.html">
            <div>
                <h1>View Three</h1>
                <p>In pellentesque faucibus vestibulum. Nulla at nulla justo, eget luctus tortor. Nulla facilisi. Duis aliquet egestas purus in blandit. Curabitur vulputate, ligula lacinia scelerisque tempor, lacus lacus ornare ante, ac egestas est urna sit amet arcu. Class aptent taciti sociosqu.</p>
            </div>
        </script>
        <div>
            <div ng-repeat="tab in tabs_html" bind-compiled-html="tab.html"></div>
        </div>
    </div>
</div>

</body>
</html>

您只需运行该应用,输入一些文字,然后点击添加按钮即可。这将添加一个标签,其中的网址相同。请参阅JS文件中的选项1,选项2和选项3中的JavaScript注释。目前,选项1已取消注释以显示其有效。如果您对此进行评论并取消注释选项2,则这是我需要工作但无法使其工作的选项。

1 个答案:

答案 0 :(得分:0)

我为你做了Plunk

如果你首先编译html怎么样,比如

  var htmlString = '<script type="text/ng-template" id="{{eisEvent.url}}">Hello Event: {{eisEvent.url}}</script>';
  var htmlElement = $compile(htmlString)($scope);
  $scope.tabs_html.push( {html: htmlElement });

您当然必须注入编译服务

myApp.controller('TabsCtrl', function ($scope, EISEventService, $compile) {