使用 AngularJS 将 HTML 插入并解析到视图中 [英] Insert and parse HTML into view using AngularJS

查看:20
本文介绍了使用 AngularJS 将 HTML 插入并解析到视图中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道当我想将 HTML 插入视图时,我使用 'ng-bind-html''ng-bind-html-unsafe'.

我不知道的是如何插入 HTML 并使 Angular 解析其内容

即如果有'ng-repeat',我想让Angular解析它?

更新 1:

示例:

HTML:

<div ng-repeat="t in ts" ng-bind-html-unsafe="t.html()"></div>

JS:

function Controller($scope) {$scope.ts = {obj1: new obj(), obj2: new obj(), ob3: new obj()};}函数对象(){//这可能是<div ng-repeat="s in somthing">{{s}}</div>"//或<ul><li ng-repeat="s in somthing">{{s.k}}</li></ul>"//或者是其他东西var_html;this.html = 函数(){返回_html;}}

我尝试使用上述方法,但 Angular 只是按原样打印 {{s}}{{s.k}}.

解决方案

您可以使用 $compile 服务 (文档).

app.run(function($rootScope, $compile, $rootElement) {//我们将创建一个新范围用作视图的上下文.$scope = $rootScope.$new();$scope.model = [{name: 'first'}, {name: 'second'}, {name: 'third'}];//调用 `$compile(html)` 返回一个函数,当调用时//一个上下文对象,将编译后的 HTML 链接到给定的上下文(例如//将视图中基于作用域的表达式绑定到传入的作用域).var html = "<div ng-repeat='m in model'>{{m.name}}</div>";var linkingFunction = $compile(html);var elem = linkingFunction($scope);//然后您可以像平常一样使用 DOM 元素.$rootElement.append(elem);});

在本例中,我已将视图附加到 $rootElement(引导模块时使用的元素,通常由 ng-app指示);在许多情况下,您将在指令的链接函数中执行此类操作,并且可以访问相关元素.当然,您可以使用 jQuery 或 jqLit​​e 获取原始 HTML,但请记住在执行此操作之前在链接的作用域上至少允许一个摘要循环(否则 HTML 将尚未使用作用域中的值进行更新).

工作示例:http://jsfiddle.net/BinaryMuse/QHhVR/

ng-include 指令的内部,Angular 正在做这件事:

$compile(currentElement.contents())(currentScope);

<小时>

[更新]

这是一个更完整的示例,它演示了更接近您更新的问题的内容:

app.controller("MainController", function($scope) {$scope.ts = [{元素:['一','二','三'],html: '<div ng-repeat="elem in t.elements">{{elem}}</div>'},{事情:[8, 9, 10],添加:功能(目标){var last = target[target.length - 1];target.push(last + 1);},html: '<ul><li ng-repeat="num in t.things">{{num}}</li>'+'<li><button ng-click="t.add(t.things)">更多</button></li></ul>'}];});app.directive("bindCompiledHtml", function($compile, $timeout) {返回 {模板:'<div></div>',范围: {rawHtml: '=bindCompiledHtml'},链接:功能(范围,元素,属性){scope.$watch('rawHtml', function(value) {如果(!值)返回;//我们想使用这个指令的范围之外//(它本身是一个隔离范围).var newElem = $compile(value)(scope.$parent);elem.contents().remove();elem.append(newElem);});}};});

<div ng-repeat="t in ts" bind-compiled-html="t.html"></div>

工作示例:http://jsfiddle.net/BinaryMuse/VUYCG/

HTML 片段使用 t.elementst.things 毫无价值,因为 t 是由ng-repeatouter HTML 中.如果你愿意,你可以做一些范围体操来让这个更好一点.

What I know is when I want to insert HTML into view, I use 'ng-bind-html' or 'ng-bind-html-unsafe'.

What I don't know, is how to insert HTML and make Angular parse its content

i.e. if there is 'ng-repeat', I want Angular to parse it?

Update 1:

example:

HTML:

<div ng-repeat="t in ts" ng-bind-html-unsafe="t.html()"></div>

JS:

function Controller($scope) {
    $scope.ts = {obj1: new obj(), obj2: new obj(), ob3: new obj()};

}

function obj() {
    // which may be "<div ng-repeat="s in somthing">{{s}}</div>"
    // or "<ul><li ng-repeat="s in somthing">{{s.k}}</li></ul>"
    // or something else
    var _html;

    this.html = function() {
        return _html;
    }
}

I tried using the above, but Angular just print {{s}} or {{s.k}} as it is.

解决方案

You can compile arbitrary HTML into an angular view with the $compile service (docs).

app.run(function($rootScope, $compile, $rootElement) {
  // We'll create a new scope to use as the context for the view.
  $scope = $rootScope.$new();
  $scope.model = [{name: 'first'}, {name: 'second'}, {name: 'third'}];

  // Calling `$compile(html)` returns a function that, when called with
  // a context object, links the compiled HTML to the given context (e.g.
  // binds scope-based expressions in the view to the passed in scope).
  var html = "<div ng-repeat='m in model'>{{m.name}}</div>";
  var linkingFunction = $compile(html);
  var elem = linkingFunction($scope);

  // You can then use the DOM element like normal.
  $rootElement.append(elem);
});

In this case, I've attached the view to the $rootElement (which is the element that was used when bootstrapping the module, usually by the ng-app directive); in many cases, you'll do this kind of thing in a directive's linking function and will have access to the element in question. You can, of course, get the raw HTML using jQuery or jqLite, but remember to allow at least one digest cycle on the linked scope before you do so (or else the HTML won't yet have been updated with values from the scope).

Working example: http://jsfiddle.net/BinaryMuse/QHhVR/

Down in the bowels of the ng-include directive, Angular's doing this very thing:

$compile(currentElement.contents())(currentScope);


[Update]

Here is a more complete example that demonstrates something a bit closer to your updated question:

app.controller("MainController", function($scope) {
  $scope.ts = [
    {
      elements: ['one', 'two', 'three'],
      html: '<div ng-repeat="elem in t.elements">{{elem}}</div>'
    },
    {
      things: [8, 9, 10],
      add: function(target) {
        var last = target[target.length - 1];
        target.push(last + 1);
      },
      html: '<ul><li ng-repeat="num in t.things">{{num}}</li>' +
        '<li><button ng-click="t.add(t.things)">More</button></li></ul>'
    }
  ];
});

app.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);
      });
    }
  };
});

<div ng-controller="MainController">
  <div ng-repeat="t in ts" bind-compiled-html="t.html"></div>
</div>

Working example: http://jsfiddle.net/BinaryMuse/VUYCG/

It's worth nothing that the HTML snippets use t.elements and t.things because t is the scope value that is created by the ng-repeat in the outer HTML. You could do some scope gymnastics to make this a bit nicer if you like.

这篇关于使用 AngularJS 将 HTML 插入并解析到视图中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆