从数据库编译动态HTML字符串 形势

从数据库编译动态HTML字符串 形势,html,dom,dynamic,angularjs,compilation,Html,Dom,Dynamic,Angularjs,Compilation,Angular应用程序中嵌套了一个名为Page的指令,由一个控制器支持,该控制器包含一个带有ng bind html不安全属性的div。这被分配给名为“pageContent”的$scope变量。该变量从数据库中动态生成HTML。当用户翻到下一页时,会调用DB,并且pageContent变量被设置为这个新的HTML,通过ng bind HTML在屏幕上呈现。代码如下: 页面指令 angular.module('myApp.directives') .directive('myPage',

Angular应用程序中嵌套了一个名为Page的指令,由一个控制器支持,该控制器包含一个带有ng bind html不安全属性的div。这被分配给名为“pageContent”的$scope变量。该变量从数据库中动态生成HTML。当用户翻到下一页时,会调用DB,并且pageContent变量被设置为这个新的HTML,通过ng bind HTML在屏幕上呈现。代码如下:

页面指令

angular.module('myApp.directives')
    .directive('myPage', function ($compile) {

        return {
            templateUrl: 'page.html',
            restrict: 'E',
            compile: function compile(element, attrs, transclude) {
                // does nothing currently
                return {
                    pre: function preLink(scope, element, attrs, controller) {
                        // does nothing currently
                    },
                    post: function postLink(scope, element, attrs, controller) {
                        // does nothing currently
                    }
                }
            }
        };
    });
页面指令的模板(“上面templateUrl属性中的Page.html”)

这很有效。我们从数据库中看到页面的HTML在浏览器中呈现得很好。当用户翻到下一页时,我们会看到下一页的内容,依此类推。到目前为止还不错

问题 这里的问题是,我们希望在页面内容中包含交互式内容。例如,HTML可能包含一个缩略图,当用户单击它时,Angular应该做一些很棒的事情,比如显示一个弹出模式窗口。我在数据库的HTML字符串中放置了Angular方法调用(ng click),但是Angular当然不会识别方法调用或指令,除非它以某种方式解析HTML字符串,识别并编译它们

在我们的数据库中

第1页内容:

<p>Here's a cool pic of a lion. <img src="lion.png" ng-click="doSomethingAwesone('lion', 'showImage')" > Click on him to see a large image.</p>
我不知道如何从数据库的HTML字符串中调用“doSomethingAwesome”方法。我意识到Angular必须以某种方式解析HTML字符串,但是如何解析呢?我读过一些关于$compile服务的含糊不清的文字,并复制和粘贴了一些示例,但没有任何效果。此外,大多数示例仅显示在指令的链接阶段设置的动态内容。我们希望页面在应用程序的整个生命周期中保持活力。它在用户翻页时不断接收、编译和显示新内容

从抽象意义上讲,我想你可以说,我们正在尝试在Angular应用程序中动态嵌套Angular块,并且需要能够将它们进行交换


我已经多次阅读了各种各样的Angle文档,以及各种各样的博客文章,JS对人们的代码进行了修改。我不知道我是否完全误解了,或者只是错过了一些简单的东西,或者可能是我太慢了。在任何情况下,我都可以使用一些建议。

ng bind html unsafe
仅将内容呈现为html。它不会将角度范围绑定到生成的DOM。为此,您必须使用
$compile
服务。我创建它是为了演示如何使用
$compile
创建一个指令来呈现用户输入的动态HTML并绑定到控制器的作用域。消息来源如下

demo.html

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <h1>Compile dynamic HTML</h1>
    <div ng-controller="MyController">
      <textarea ng-model="html"></textarea>
      <div dynamic="html"></div>
    </div>
  </body>

</html>

编译动态HTML
script.js

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

app.directive('dynamic', function ($compile) {
  return {
    restrict: 'A',
    replace: true,
    link: function (scope, ele, attrs) {
      scope.$watch(attrs.dynamic, function(html) {
        ele.html(html);
        $compile(ele.contents())(scope);
      });
    }
  };
});

function MyController($scope) {
  $scope.click = function(arg) {
    alert('Clicked ' + arg);
  }
  $scope.html = '<a ng-click="click(1)" href="#">Click me</a>';
}
var-app=angular.module('app',[]);
应用程序指令('dynamic',函数($compile){
返回{
限制:“A”,
替换:正确,
链接:功能(范围、元素、属性){
作用域.$watch(attrs.dynamic,函数(html){
ele.html(html);
$compile(ele.contents())(范围);
});
}
};
});
函数MyController($scope){
$scope.click=函数(arg){
警报('单击'+参数);
}
$scope.html='';
}

在angular 1.2.10中,
作用域。$watch(attrs.dynamic,function(html){
行返回无效字符错误,因为它试图查看html文本的
attrs.dynamic
的值

我通过从scope属性中获取属性来修复这个问题

 scope: { dynamic: '=dynamic'}, 
我的例子

angular.module('app')
  .directive('dynamic', function ($compile) {
    return {
      restrict: 'A',
      replace: true,
      scope: { dynamic: '=dynamic'},
      link: function postLink(scope, element, attrs) {
        scope.$watch( 'dynamic' , function(html){
          element.html(html);
          $compile(element.contents())(scope);
        });
      }
    };
  });

在谷歌讨论组中找到。对我有用

var $injector = angular.injector(['ng', 'myApp']);
$injector.invoke(function($rootScope, $compile) {
  $compile(element)($rootScope);
});
你可以用

ng绑定html

指令动态绑定html。 但是,您必须通过$sce服务获取数据

请看现场演示

var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope,$sce){
$scope.getHtml=function(){
返回$sce.trustAsHtml(“Hi Rupesh Hi dfdfdfdf!sdafsdfsdfasdf”);
}
});
尝试下面的代码通过attr绑定html
试试这个element.html(scope.dynamic);
而不是element.html(attr.dynamic)非常感谢,Buu!创建attribute指令和添加scope watch函数是我所缺少的两件事。现在这一切都正常了,我想我将再次阅读指令和$compile,以便更好地理解引擎盖下发生的事情。我也是!Angular团队真的可以在这方面改进文档。
$compile(ele.contents())(范围)
-这一行解决了我不编译动态添加的角度组件的问题。谢谢。@BuuNguyen在teplateURL中假设如果您使用ng bind html包含一些动态HTMLPage,那么使用compile Doesn t work会从某些不安全的内容中产生错误另一方使用trustAsHTml只删除不安全的错误不编译,任何建议?我喜欢这个例子,但它没有让我的工作。我有一个开关语句,这是由于用户的选择而发生的,所以它是动态的。根据这一点,我想插入包含html的指令。如果我把指令放在自然引导阶段,它就可以工作。但是我有一个简单的例子,就是不触发---case'info':$scope.htmlString=$sce.trustAsHtml('dddzzz');break;---当我想做类似--$compile($sce.trustAsHtml('dddzzz'))的事情时;关于解决方法等有什么想法吗?您好,如果我使用element.html,它会返回我TypeError:无法调用null的方法'insertBefore'。所以在谷歌搜索了一段时间后,我发现我必须使用element.append,但如果我在多个地方使用该指令,它会生成多重html。因此,2个指令会生成4个相同的html代码。谢谢您的回答.我不会在你的位置上使用append,我今晚会看一看,然后再给你回复。老实说,我在很多地方都使用过这个指令
var app = angular.module('app', []);

app.directive('dynamic', function ($compile) {
  return {
    restrict: 'A',
    replace: true,
    link: function (scope, ele, attrs) {
      scope.$watch(attrs.dynamic, function(html) {
        ele.html(html);
        $compile(ele.contents())(scope);
      });
    }
  };
});

function MyController($scope) {
  $scope.click = function(arg) {
    alert('Clicked ' + arg);
  }
  $scope.html = '<a ng-click="click(1)" href="#">Click me</a>';
}
 scope: { dynamic: '=dynamic'}, 
angular.module('app')
  .directive('dynamic', function ($compile) {
    return {
      restrict: 'A',
      replace: true,
      scope: { dynamic: '=dynamic'},
      link: function postLink(scope, element, attrs) {
        scope.$watch( 'dynamic' , function(html){
          element.html(html);
          $compile(element.contents())(scope);
        });
      }
    };
  });
var $injector = angular.injector(['ng', 'myApp']);
$injector.invoke(function($rootScope, $compile) {
  $compile(element)($rootScope);
});
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$sce) {
    $scope.getHtml=function(){
   return $sce.trustAsHtml("<b>Hi Rupesh hi <u>dfdfdfdf</u>!</b>sdafsdfsdf<button>dfdfasdf</button>");
   }
});

  <body ng-controller="MainCtrl">
<span ng-bind-html="getHtml()"></span>
  </body>
.directive('dynamic', function ($compile) {
    return {
      restrict: 'A',
      replace: true,
      scope: { dynamic: '=dynamic'},
      link: function postLink(scope, element, attrs) {
        scope.$watch( 'attrs.dynamic' , function(html){
          element.html(scope.dynamic);
          $compile(element.contents())(scope);
        });
      }
    };
  });