如何正确复制/克隆DOM元素,然后将其粘贴/插入Angular.js中的HTML元素?

时间:2015-02-06 18:41:18

标签: angularjs dom coffeescript angularjs-ng-repeat clone

所以我有一个使用Angular.js的大型webapp。
这个webapp的一小部分有侧边栏,目前显示两个div容器:一个显示用户配置文件统计信息(缩略图,信誉,消息,一些技巧.etc)和第二个是滑块(angular-ui)旋转木马显示一些图像。

我想要做的是克隆整个技能侧栏并将此克隆的DOM对象粘贴到滑块中作为另一张幻灯片,但转换为HTML元素。

以下是此滑块的代码:

<div id="scrolling-sidebar">
  <carousel interval="myInterval">
    <slide ng-repeat="slide in slides" active="slide.active">
      <a href="{{slide.link}}" ng-if="$index != 1">
        <img ng-src="{{slide.image}}" />
      </a>
      <a href="{{slide.link}}" ng-bind-html="slide.content"></a>
    </slide>
  </carousel>
</div>

这是整个侧边栏控制器.coffee脚本的一部分:

'use strict'

angular.module('someApp')
  .controller 'SidebarCtrl', ($scope, $modal, $http, $location, settings) ->


    $scope.myInterval = 5000
    $scope.slides = [
        {
            image: "/images/_getpro_banners1.png"
            link: "#/get-pro"
        }
        {
            content: $("#profile-skills-sidebar").clone()
            link: "#/get-pro" 
        }
        {
            image: "/images/_getpro_banners2.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners3.png"
            link: "#/get-noticed"
        }
        {
            image: "/images/_getpro_banners4.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners5.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners6.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners7.png"
            link: "#/get-pro"
        }
    ]
    console.log "Cloned dom element: " + $scope.slides[1].content[0].html()

运行此webapp(基本上刷新网页)时,我在开发人员控制台中收到以下错误:TypeError: Cannot read property 'html' at new <anonymous> (http://127.0.0.1:9000/scripts/controllers/sidebar.js:39:69) of undefined对应于编译为js sidebar.js文件中的此行console.log("Cloned dom element: " + $scope.slides[1].content[0].html());

所以这基本上意味着,这一行content: $("#profile-skills-sidebar").clone()不能像预期的那样工作 - 看起来甚至没有克隆DOM元素。

因此,第二张幻灯片是[object Object]而是复制了技能栏。

我加载了jQuery(使用bower和grunt进行前端开发),我可以在浏览器devtools中使用:

> var skills = $("#profile-skills-sidebar");
< undefined
> skills
< [<div id="profile-skills-sidebar">…</div>]
> skills[0]
< <div id="profile-skills-sidebar">…</div>

我尝试在.coffee脚本中创建指令:

.directive "skillsBarSlide", ['$compile', ($scope, $compile, $timeout) ->
    restrict: 'A'
    #template: '<a href="{{slide.link}}"></a>'
    link: (scope, elem, attrs) ->
        $timeout( -> 
            scope.slides[1].content = angular.element($("#profile-skills-sidebar")).copy()
            element.append($compile(scope.slides[1].content)(scope))
        )
  ]

但它没有用。

那么我必须做些什么步骤:
1.克隆需要DOM元素
2.可能将其转换为HTML元素的字符串(因为克隆的DOM将是一个对象)
3.插入所需的div容器

我知道我在这里可能需要$ sce,$ compile可能是$ sanitize(我已经阅读了一些角度文档),但是我很有棱角分明,还没有理解它。

感谢您的最终帮助。

1 个答案:

答案 0 :(得分:0)

好的,所以我终于成功了。

sidebar.coffee

'use strict'

angular.module('someApp')
  .controller 'SidebarCtrl', ($scope, $sce, $modal, $http, $location, settings) ->


    $scope.myInterval = 5000
    $scope.slides = [
        {
            image: "/images/_getpro_banners1.png"
            link: "#/get-pro"
        }
        {
            content: ''
            link: "#/get-pro" 
        }
        {
            image: "/images/_getpro_banners2.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners3.png"
            link: "#/get-noticed"
        }
        {
            image: "/images/_getpro_banners4.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners5.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners6.png"
            link: "#/get-pro"
        }
        {
            image: "/images/_getpro_banners7.png"
            link: "#/get-pro"
        }
    ]

    [...]some_code[...]

    $scope.renderHTML = ->
        $scope.slides[1].content = "<div id='profile-skills-sidebar'>" + $("#profile-skills-sidebar").clone().html() + "</div>"
        #console.log "Cloned dom element: " + $scope.slides[1].content
        $sce.trustAsHtml($scope.slides[1].content)

sidebar.html

<div id="scrolling-sidebar" ng-hide="{{hasPro}}">
  <carousel interval="myInterval">
    <slide ng-repeat="slide in slides" active="slide.active">
      <a href="{{slide.link}}" ng-if="$index != 1">
        <img ng-src="{{slide.image}}" />
      </a>
      <a href="{{slide.link}}" class="skills-bar-slide" ng-if="$index == 1" ng-bind-html="renderHTML()"></a>
    </slide>
  </carousel>
</div>

因此,必须使用.html() jQuery / jqLit​​e函数从克隆为JS对象的DOM元素中提取HTML元素。
然后使用Strict Contextual Escaping trustAsHtml() 方法,验证 ng-bind-html 指令的HTML代码。
基本上就是这样。