AngularJS多个表达式在插值中与URL连接

use*_*464 44 javascript youtube interpolation concatenation angularjs

我知道这很长,但请耐心等待.问题很容易理解,只需要写一些文字就可以完全解释它.

现在我收到了这个错误

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
Run Code Online (Sandbox Code Playgroud)

我已经完成了文档中的所有阅读,但我仍然无法找到解决问题的方法.

我在私有在线源上使用$ 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"
       },
    },
...
Run Code Online (Sandbox Code Playgroud)

我正在尝试将每个项目的videoId插入到嵌入YouTube视频的HTML iframe中.在我的controller.js文件中,我在$ http.get之后设置了promise对象

$http.get('privatesource').success(function(data) {
  $scope.videoList = data.items;
});
Run Code Online (Sandbox Code Playgroud)

所以现在变量"$ scope.videoList"被映射到data.items,它有很多视频元素.在我的HTML文件中,我可以使用查找每个视频的videoID

<ul class="videos">
  <li ng-repeat="video in videoList">
    <span>{{video.id.videoID}}</span>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

这列出了所有的videoID.但是,如果我尝试将这些值连接到URL(例如https://youtube.com/embed/),则它无效.

<div ng-repeat="video in videoList">
    <iframe id="ytplayer" type="text/html" width="640" height="360" 
     ng-src="https://www.youtube.com/embed/{{video.id.videoId}}" 
     frameborder="0" allowfullscreen></iframe>
</div>
Run Code Online (Sandbox Code Playgroud)

有没有办法让videoID插入youtube网址?我已经尝试使用$ sceDelegateProvider进行白名单,如下所示,但它仍然无法正常工作

$sceDelegateProvider.resourceUrlWhitelist([
  'self',
  'https://www.youtube.com/**']);
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏.谢谢!

Tom*_*cer 77

@ tasseKATT的答案(不需要控制器函数)的替代方法是在表达式中直接使用字符串连接:

angular.module('myApp')
  .filter('youtubeEmbedUrl', function ($sce) {
    return function(videoId) {
      return $sce.trustAsResourceUrl('http://www.youtube.com/embed/' + videoId);
    };
  });
Run Code Online (Sandbox Code Playgroud)
<div ng-src="{{ video.id.videoId | youtubeEmbedUrl }}"></div>
Run Code Online (Sandbox Code Playgroud)

我发现这在使用SVG图标精灵时特别有用,它需要你使用xlink:hrefSVG use标签上的属性- 这受到相同的SCE规则的约束.在我需要使用sprite的地方重复控制器功能看起来很傻,所以我使用了filter方法.

angular.module('myApp')
  .filter('svgIconCardHref', function ($sce) {
    return function(iconCardId) {
      return $sce.trustAsResourceUrl('#s-icon-card-' + iconCardId);
    };
  });
Run Code Online (Sandbox Code Playgroud)
<svg><use xlink:href="{{ type.key | svgIconCardHref }}"></use></svg>
Run Code Online (Sandbox Code Playgroud)

注意:我之前在表达式中尝试过简单的字符串连接.然而,这导致了一些意想不到的行为,浏览器会在Angular有机会解析它并用真实替换之前解释表达式href.由于没有ng-src相应的use标签,xlink:href我选择了过滤器,这似乎解决了这个问题.

  • 你可以尝试将静态字符串放在curlies中:`xlink:href ="{{'/ path/to/something /'+(type.key | svgIconCardHref)}}"` (2认同)

tas*_*ATT 57

从1.2开始,你只能将一个表达式绑定到*[src],*[ng-src]或action.你可以在这里阅读更多相关信息.

试试这个:

在控制器中:

$scope.getIframeSrc = function (videoId) {
  return 'https://www.youtube.com/embed/' + videoId;
};
Run Code Online (Sandbox Code Playgroud)

HTML:

ng-src="{{getIframeSrc(video.id.videoId)}}"
Run Code Online (Sandbox Code Playgroud)

请注意,您仍然需要将其列入白名单,否则您将获得locked loading resource from url not allowed by $sceDelegate policy.

  • @molerat 通过在配置块中注入并使用 `$sceDelegateProvider` 。例如:`$sceDelegateProvider.resourceUrlWhitelist(['self', 'https://www.youtube.com/**']);` (2认同)

Ser*_*rge 5

在控制器中:

app.filter('trustAsResourceUrl', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsResourceUrl(val);
    };
}]);
Run Code Online (Sandbox Code Playgroud)

在 HTML 中:

ng-src="('https://www.youtube.com/embed/' + video.id.videoId) | trustAsResourceUrl"
Run Code Online (Sandbox Code Playgroud)