it-swarm.com.de

AngularJS mehrere Ausdrücke, die in Interpolation mit einer URL verkettet werden

Ich weiß, das ist lang, aber bitte ertragen Sie mich. Das Problem ist leicht zu verstehen, man muss nur etwas schreiben, um es vollständig zu erklären.

Im Moment bekomme ich diesen Fehler

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

Ich habe alles in der Dokumentation gelesen, finde aber immer noch keine Lösung für mein Problem.

Ich verwende $ http.get für eine private Online-Quelle, die Daten enthält, die der Form einer Json-Datei ähneln (daher kann ich die Daten nicht ändern). Die Daten sehen so aus:

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

Ich versuche, die videoId jedes Elements in meinen HTML-Iframe zu interpolieren, der das YouTube-Video einbettet. In meiner controller.js-Datei setze ich das Versprechungsobjekt nach dem $ http.get als solches

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

Nun wird die Variable "$ scope.videoList" auf data.items abgebildet, die viele Videoelemente enthält. In meiner HTML-Datei kann ich die Video-ID jedes Videos mit abrufen

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

und das listet alle videoIDs auf. Wenn ich jedoch versuche, diese Werte mit einer URL wie https://youtube.com/embed/ zu verketten, funktioniert dies nicht.

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

Gibt es eine Möglichkeit, die Video-ID in die Youtube-URL zu interpolieren? Ich habe das Whitelisting mit dem $ sceDelegateProvider wie folgt versucht, aber es funktioniert immer noch nicht

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

Jede Hilfe wird geschätzt. Vielen Dank!

44
user2669464

Seit 1.2 können Sie nur einen Ausdruck an * [src], * [ng-src] oder action binden. Sie können mehr darüber lesen hier .

Versuchen Sie es stattdessen:

Im Controller:

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

HTML:

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

Beachten Sie, dass Sie die Whitelist weiterhin wie gewohnt verwenden müssen. Andernfalls erhalten Sie locked loading resource from url not allowed by $sceDelegate policy.

57
tasseKATT

Eine Alternative zur Antwort von @ tasseKATT (die keine Controller-Funktion erfordert) ist die Verwendung von zeichenfolgenverkettung direkt im Ausdruck ein 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>

Ich habe dies besonders nützlich gefunden, wenn Sie SVG-Icon-Sprites verwenden. Dazu müssen Sie das xlink:href-Attribut für den SVG-Tag use verwenden. Dies unterliegt den gleichen SCE-Regeln. Das Wiederholen der Controller-Funktion überall, wo ich einen Sprite brauchte, schien dumm zu sein, deshalb verwendete ich stattdessen die Filtermethode.

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>

Hinweis: Ich hatte zuvor nur eine einfache Verkettung von Zeichenfolgen innerhalb des Ausdrucks versucht. Dies führte jedoch zu einem unerwarteten Verhalten, bei dem der Browser den Ausdruck interpretierte, bevor Angular die Möglichkeit hatte, ihn zu analysieren und durch die echte href zu ersetzen. Da es keine ng-src-Entsprechung für den xlink:href-Tag des use-Tags gibt, habe ich mich für den Filter entschieden, der das Problem offenbar gelöst zu haben scheint.

76
Tom Spencer

im 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"
2
Serge

Meine Version ist angular.min.1.5.8.js Ich hatte das gleiche Problem mit einem Formular. Ich habe es gelöst, indem ich das Attribut action = URL durch ng-action = URL geändert habe.

0
Francisco