AngularJS multiple expressions concatenating in interpolation with a URL

巧了我就是萌 提交于 2019-11-26 09:36:11

问题


I know this is long, but please bear with me. The problem is easy to understand, just takes some writing to fully explain it.

Right now I\'m getting this error

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

I\'ve done all the reading in the documentation, but I still can\'t find a workaround for my problem.

I\'m using $http.get on a private online source that has data that is similar to the form of a json file (so I can\'t modify the data). The data looks like this:

...
\"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\"
       },
    },
...

I\'m trying to interpolate the videoId of each item into my HTML iframe that embeds the YouTube video. In my controller.js file, I\'m setting the promise object after the $http.get as such

$http.get(\'privatesource\').success(function(data) {
  $scope.videoList = data.items;
});

So now the variable \"$scope.videoList\" is mapped to data.items, which has a lot of video elements. In my HTML file, I can retrieve the videoID of each video by using

<ul class=\"videos\">
  <li ng-repeat=\"video in videoList\">
    <span>{{video.id.videoID}}</span>
  </li>
</ul>

and this lists all the videoID\'s. But if I try to concatenate these values to a URL, like https://youtube.com/embed/, it does not work.

<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>

Is there a way that I can get the videoID to be interpolated into the youtube URL? I\'ve tried whitelisting by using the $sceDelegateProvider as follows but it still does not work

$sceDelegateProvider.resourceUrlWhitelist([
  \'self\',
  \'https://www.youtube.com/**\']);

Any help is appreciated. Thanks!


回答1:


Since 1.2 you can only bind one expression to *[src], *[ng-src] or action. You can read more about it here.

Try this instead:

In Controller:

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

HTML:

ng-src="{{getIframeSrc(video.id.videoId)}}"

Note that you still need to whitelist it as you have, or you will get locked loading resource from url not allowed by $sceDelegate policy.




回答2:


An alternative to @tasseKATT's answer (which doesn't require a controller function) is to use string concatenation directly in the expression a filter:

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>

I've found this particularly useful when using SVG icon sprites, which requires you to use the xlink:href attribute on the SVG use tag - this is subject to the same SCE rules. Repeating the controller function everywhere I needed to use a sprite seemed silly so I used the filter method instead.

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>

Note: I had previously tried just simple string concatenation inside the expression. However this led to some unexpected behaviour where the browser would interpret the expression before Angular had a chance to parse it and replace with the real href. Since there is no ng-src equivalent for the use tag's xlink:href I opted for the filter, which seems to have solved the issue.




回答3:


in controller:

app.filter('trustAsResourceUrl', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsResourceUrl(val);
    };
}]);

in html:

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



回答4:


My version is angular.min.1.5.8.js I had the same issue with a form. I resolved it by changing the attribute action=URL by ng-action=URL.



来源:https://stackoverflow.com/questions/23405162/angularjs-multiple-expressions-concatenating-in-interpolation-with-a-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!