AngularJS 多个表达式在插值中与 URL 连接
Posted
技术标签:
【中文标题】AngularJS 多个表达式在插值中与 URL 连接【英文标题】:AngularJS multiple expressions concatenating in interpolation with a URL 【发布时间】:2014-06-17 18:45:34 【问题描述】:我知道这很长,但请耐心等待。这个问题很容易理解,只需要写一些文字就能完全解释清楚。
现在我遇到了这个错误
Error: [$interpolate:noconcat] Error while interpolating:
Strict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required.
See http://docs.angularjs.org/api/ng.$sce
我已经阅读了文档中的所有内容,但仍然找不到解决问题的方法。
我在私人在线资源上使用 $http.get,该资源具有类似于 json 文件形式的数据(因此我无法修改数据)。数据如下所示:
...
"items": [
"kind": "youtube#searchResult",
"etag": "\"N5Eg36Gl054SUNiWWc-Su3t5O-k/A7os41NAa_66TUu-1I-VxH70Rp0\"",
"id":
"kind": "youtube#video",
"videoID": "MEoSax3BEms"
,
,
"kind": "youtube#searchResult",
"etag": "\"N5Eg36Gl054SUNiWWc-Su3t5O-k/VsH9AmnQecyYBLJrl1g3dhewrQo\"",
"id":
"kind": "youtube#video",
"videoID": "oUBqFlRjVXU"
,
,
...
我正在尝试将每个项目的 videoId 插入到嵌入 YouTube 视频的 html iframe 中。在我的 controller.js 文件中,我在 $http.get 之后设置了 promise 对象
$http.get('privatesource').success(function(data)
$scope.videoList = data.items;
);
所以现在变量“$scope.videoList”被映射到data.items,它有很多视频元素。在我的 HTML 文件中,我可以使用
检索每个视频的 videoID<ul class="videos">
<li ng-repeat="video in videoList">
<span>video.id.videoID</span>
</li>
</ul>
这会列出所有的 videoID。 但是如果我尝试将这些值连接到一个 URL,比如https://youtube.com/embed/,它就不起作用了。
<div ng-repeat="video in videoList">
<iframe id="ytplayer" type="text/html"
ng-src="https://www.youtube.com/embed/video.id.videoId"
frameborder="0" allowfullscreen></iframe>
</div>
有没有办法让我将 videoID 插入到 youtube URL 中?我已经尝试使用 $sceDelegateProvider 将其列入白名单,但它仍然不起作用
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'https://www.youtube.com/**']);
感谢任何帮助。谢谢!
【问题讨论】:
【参考方案1】:@tasseKATT 的答案(不需要控制器函数)的替代方法是直接在表达式中使用 字符串连接 过滤器:
angular.module('myApp')
.filter('youtubeEmbedUrl', function ($sce)
return function(videoId)
return $sce.trustAsResourceUrl('http://www.youtube.com/embed/' + videoId);
;
);
<div ng-src=" video.id.videoId | youtubeEmbedUrl "></div>
我发现这在使用 SVG 图标精灵时特别有用,它要求您在 SVG use
标记上使用 xlink:href
属性 - 这符合相同的 SCE 规则。在需要使用精灵的任何地方重复控制器功能似乎很愚蠢,所以我改用了过滤器方法。
angular.module('myApp')
.filter('svgIconCardHref', function ($sce)
return function(iconCardId)
return $sce.trustAsResourceUrl('#s-icon-card-' + iconCardId);
;
);
<svg><use xlink:href=" type.key | svgIconCardHref "></use></svg>
注意:我之前在表达式中尝试过简单的字符串连接。然而,这导致了一些意想不到的行为,浏览器会在 Angular 有机会解析表达式并替换为真正的 href
之前解释表达式。由于use
标签的xlink:href
没有ng-src
等效项,因此我选择了过滤器,这似乎解决了问题。
【讨论】:
感谢您的解决方案。如果xlink:href
有任何字符串连接,如xlink:href="/path/to/something/ type.key | svgIconCardHref "
,则它不起作用。
您可以尝试将静态字符串放入花括号中:xlink:href=" '/path/to/something/' + (type.key | svgIconCardHref) "
【参考方案2】:
从 1.2 开始,您只能将一个表达式绑定到 *[src]、*[ng-src] 或操作。你可以阅读更多关于它的信息here。
试试这个:
在控制器中:
$scope.getIframeSrc = function (videoId)
return 'https://www.youtube.com/embed/' + videoId;
;
HTML:
ng-src="getIframeSrc(video.id.videoId)"
请注意,您仍然需要将其列入白名单,否则您将收到locked loading resource from url not allowed by $sceDelegate policy
。
【讨论】:
+1 并感谢您的回答,因为所有其他答案都依赖于将 URL 硬编码为 $sce 可信资源,而不是将其填充为模板项。 谢谢。您如何将网址列入白名单? @molerat 通过在配置块中注入和使用$sceDelegateProvider
。例如:$sceDelegateProvider.resourceUrlWhitelist(['self', 'https://www.youtube.com/**']);
@tasseKATT 谢谢 - 我刚刚看到这个问题已经出现了:)【参考方案3】:
在控制器中:
app.filter('trustAsResourceUrl', ['$sce', function ($sce)
return function (val)
return $sce.trustAsResourceUrl(val);
;
]);
在html中:
ng-src="('https://www.youtube.com/embed/' + video.id.videoId) | trustAsResourceUrl"
【讨论】:
【参考方案4】:我的版本是angular.min.1.5.8.js
我对表格有同样的问题。我通过 ng-action=URL 更改属性 action=URL 来解决它。
注意:这不起作用,因为ng-action
不是真正的指令。
【讨论】:
以上是关于AngularJS 多个表达式在插值中与 URL 连接的主要内容,如果未能解决你的问题,请参考以下文章