Question

En travaillant avec l'API de themoviedb.com, je demande à l'utilisateur de saisir un champ de saisie et d'envoyer la requête API à chaque frappe.En testant cela, parfois l'affiche du film serait "nulle" au lieu du poster_path prévu.Je préfère utiliser par défaut une image d'espace réservé pour indiquer qu'une affiche n'a pas été trouvée avec la requête API.

Donc, parce que l'intégralité de l'URL poster_path n'est pas proposée par l'API, et comme j'utilise un ng-repeat AngularJS, je dois structurer la balise d'image comme ceci (en utilisant des données factices pour économiser de l'espace) :

<img ng-src="{{'http://example.com/'+movie.poster_path}}" alt="">

Mais ensuite la console me renvoie une erreur due à une mauvaise requête car le chemin complet de l'image n'est pas renvoyé.J'ai essayé d'utiliser l'invite OR :

{{'http://example.com/'+movie.poster_path || 'http://example.com/missing.jpg'}}

Mais cela ne fonctionne pas dans ce cas.Alors maintenant avec le javascript.Je n'arrive pas à obtenir la source de l'image en utilisant getElementsByTagName ou getElementByClass, et l'utilisation de getElementById semble ne récupérer que la première répétition et rien d'autre, ce que je pensais être le cas.Mais même dans ce cas, je n'arrive pas à remplacer la source de l'image.Voici la structure de code que j'ai essayée :

<input type="text" id="search">
<section ng-controller="movieSearch">
  <article ng-repeat="movie in movies">
    <img id="myImage" src="{{'http://example.com/'+movie.poster_path}}" alt="">
  </article>
</section>

<script>
function movieSearch($scope, $http){
  var string,
      replaced,
      imgSrc,
      ext,
      missing;

  $(document).on('keyup', function(){
    string = document.getElementById('search').value.toLowerCase();
    replaced = string.replace(/\s+/g, '+');
    $http.jsonp('http://example.com/query='+replaced+'&callback=JSON_CALLBACK').success(function(data) {
      console.dir(data.results);
      $scope.movies = data.results;
    });
    imgSrc = document.getElementById('myImage').src;
    ext = imgSrc.split('.').pop();
    missing='http://example.com/missing.jpg';
    if(ext !== 'jpg'){
      imgSrc = missing;
    }
  });
}
</script>

Avez-vous des idées sur ce que je fais de mal, ou si ce que j'essaie peut même être fait ?

Était-ce utile?

La solution

Le premier problème que je vois est que pendant que vous définissez le movies dans un rappel asynchrone, vous recherchez la source de l'image de manière synchrone ici :

$http.jsonp('http://domain.com/query='+replaced+'&callback=JSON_CALLBACK').success(function(data) {
  console.dir(data.results);
  $scope.movies = data.results;
}); 

// This code will be executed before `movies` is populated

imgSrc = document.getElementById('myImage').src;
ext = img.split('.').pop();

Cependant, déplacer simplement le code dans le rappel ne résoudra pas le problème :

// THIS WILL NOT FIX THE PROBLEM

$http.jsonp('http://domain.com/query='+replaced+'&callback=JSON_CALLBACK').success(function(data) {
  console.dir(data.results);
  $scope.movies = data.results;

    // This will not solve the issue

    imgSrc = document.getElementById('myImage').src;
    ext = img.split('.').pop();
    // ...
}); 

C'est parce que le src les champs ne seront remplis que dans le prochain boucle de résumé.

Dans votre cas, vous devez élaguer les résultats dès que vous les recevez du rappel JSONP :

function movieSearch($scope, $http, $timeout){
  var string,
      replaced,
      imgSrc,
      ext,
      missing;

  $(document).on('keyup', function(){
    string = document.getElementById('search').value.toLowerCase();
    replaced = string.replace(/\s+/g, '+');
    $http.jsonp('http://domain.com/query='+replaced+'&callback=JSON_CALLBACK').success(function(data) {
      console.dir(data.results);
      $scope.movies = data.results;

      $scope.movies.forEach(function (movie) {
        var ext = movie.poster_path && movie.poster_path.split('.').pop();

        // Assuming that the extension cannot be
        // anything other than a jpg
        if (ext !== 'jpg') {
            movie.poster_path = 'missing.jpg';
        }
      });
    });
  });
}

Ici, vous modifiez uniquement le model derrière vous, visualisez et ne faites aucune analyse DOM post-hoc pour déterminer les échecs.


Note latérale : Vous auriez pu utiliser l'opérateur ternaire pour résoudre le problème dans la vue, mais ce n'est pas recommandé :

<!-- NOT RECOMMENDED -->
{{movie.poster_path && ('http://domain.com/'+movie.poster_path) || 'http://domain.com/missing.jpg'}}

Autres conseils

Tout d'abord, j'ai défini un filtre comme celui-ci:

à Coffeescript:

app.filter 'cond', () ->
    (default_value, condition, value) ->
        if condition then value else default_value

ou en JavaScript:

  app.filter('cond', function() {
    return function(default_value, condition, value) {
      if (condition) {
        return value;
      } else {
        return default_value;
      }
    };
  });

Ensuite, vous pouvez l'utiliser comme ceci:

{{'http://domain.com/missing.jpg' |cond:movie.poster_path:('http://domain.com/'+movie.poster_path)}}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top