如何正确地 copy/clone DOM 元素然后 paste/insert 它作为 Angular.js 中的 HTML 元素?
How to properly copy/clone DOM element and then paste/insert it as HTML element in Angular.js?
所以我有这么大的网络应用程序,它使用 Angular.js。
这个网络应用程序的一小部分有侧边栏,目前显示两个 div 容器:一个显示用户个人资料统计信息(缩略图、声誉、消息、一些技能等),其次是显示一些图像的滑块 (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 console.log("Cloned dom element: " + $scope.slides[1].content[0].html());
的这一行sidebar.js 文件。
所以这基本上意味着,这一行 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(我已经阅读了一些 angular 文档),但我对 angular 很陌生,不是吗?还没看懂
感谢您最终的帮助。
好的,我的方式终于成功了。
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 元素必须从克隆为 JS 对象的 DOM 元素中提取,使用 .html()
jQuery/jqLite 函数。
然后使用 Strict Contextual Escaping 的 trustAsHtml() 方法,为 ng-bind-html 验证此 HTML 代码指令。
基本上就是这样。
所以我有这么大的网络应用程序,它使用 Angular.js。
这个网络应用程序的一小部分有侧边栏,目前显示两个 div 容器:一个显示用户个人资料统计信息(缩略图、声誉、消息、一些技能等),其次是显示一些图像的滑块 (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 console.log("Cloned dom element: " + $scope.slides[1].content[0].html());
的这一行sidebar.js 文件。
所以这基本上意味着,这一行 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(我已经阅读了一些 angular 文档),但我对 angular 很陌生,不是吗?还没看懂
感谢您最终的帮助。
好的,我的方式终于成功了。
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 元素必须从克隆为 JS 对象的 DOM 元素中提取,使用 .html()
jQuery/jqLite 函数。
然后使用 Strict Contextual Escaping 的 trustAsHtml() 方法,为 ng-bind-html 验证此 HTML 代码指令。
基本上就是这样。