web-dev-qa-db-fra.com

AngularJS: ng-cliquez sur img? Manipuler des images (genre de galerie) avec jQuery?

Est-ce que ng-click devrait fonctionner avec la balise img?

<img ng-src="img" ng-click="openNewWindow(url)/>

myFunction est défini dans le contrôleur et $ scope est disponible… Rien n'est appelé; des idées?

(Je voudrais ouvrir un nouvel onglet/fenêtre lorsque l'image est cliquée, mais je n'entre même pas dans ma fonction)

Merci pour toute info

MODIFIER Je me suis probablement précipité lorsque j'ai posé cette question pour la première fois. Je sais maintenant pourquoi cela ne fonctionne pas dans mon cas: je manipule des images avec jQuery pour un effet de "galerie"… (si quelqu'un a une idée de comment faire cela dans AngularJS, veuillez l'activer). Voici le HTML dont je parle:

<div class="commercial-container">
    <img class="commercial" ng-src="pathToImageOrImageVar" ng-click="openNewWindow(urlToOpen)" />
    <img class="commercial" ng-src="pathToImageOrImageVar" ng-click="openNewWindow(urlToOpen2)" />
    <img class="commercial" ng-src="pathToImageOrImageVar" ng-click="openNewWindow(urlToOpen3)" />
    <img class="commercial" ng-src="pathToImageOrImageVar" ng-click="openNewWindow(urlToOpen4)" />
</div>

Et voici la jQuery avec laquelle je crée un effet de fondu d'entrée/de sortie (montrant une image, puis la suivante et ainsi de suite indéfiniment)

 function fadeInLastImg(){
    var backImg = $('.commercial-container img:first');
    backImg.hide();
    backImg.remove();
    $('.commercial-container' ).append( backImg );
    backImg.fadeIn();
};

Donc ma vraie question est la suivante:

  • Comment puis-je obtenir le même comportement qu'avec ma jQuery afin que les images soient cliquables?

Vous pouvez bien sûr fournir une meilleure solution (peut-être AngularJS) pour changer des images comme celle-ci si vous en connaissez une…

Merci

15
trainoasis

Oui, ng-click fonctionne sur les images.

Sans autre code, je ne peux pas vous expliquer pourquoi le vôtre ne fonctionne pas, mais le code que vous avez collé appellera myFunction dans le cadre du contrôleur régissant cet élément.

[~ # ~] modifier [~ # ~]

Vous n'avez certainement pas besoin d'utiliser jQuery pour cela, et vous n'y pensez pas vraiment dans un état d'esprit "angulaire" si vous le faites.

Ma suggestion est de faire une directive pour ce faire. J'ai créé un plunker avec un exemple simple de ce à quoi il pourrait ressembler.

Voici un résumé:

Remarque: Parce que l'animation est importante pour vous, assurez-vous d'inclure le ng-animate src et l'inclure en tant que dépendance dans la définition de votre module d'application. Utilisez la même version d'animation que la base angulaire.

[~ # ~] html [~ # ~]

<script src="http://code.angularjs.org/1.2.13/angular.js"></script>

<script src="http://code.angularjs.org/1.2.13/angular-animate.js"></script>

Javascript

angular.module("gallery", ['ngAnimate'])

Définissez maintenant un modèle pour votre directive:

galleryPartial.html

<div class="container">
  <img ng-src="{{image.url}}" 
       alt="{{image.name}}" 
       ng-repeat="image in images" 
       class="gallery-image fade-animation"
       ng-click="openInNewWindow($index)"
       ng-show="nowShowing==$index">
</div>

Ce modèle indique simplement "Je veux une image pour chaque élément répertorié dans le tableau" images "de la portée. La src est devrait être la propriété url de l'image, et le texte alt doit être le nom. Lorsque je clique sur une image, exécutez la fonction openInNewWindow en passant l'index de cette image dans le tableau. Enfin, masquez les images à moins que nowShowing est définie sur leur index. "

Notez également la classe fade-animation. Cela pourrait s'appeler n'importe quoi, mais c'est la classe que nous utiliserons pour définir l'animation en CSS plus tard.

Ensuite, nous écrivons la directive elle-même. C'est assez simple - il suffit d'utiliser ce modèle, puis de définir la fonction openInNewWindow, ainsi que d'itérer nowShowing via les index du tableau:

.directive('galleryExample', function($interval, $window){
  return {
    restrict: 'A',
    templateUrl: 'galleryPartial.html',
    scope: {
      images: '='
    },
    link: function(scope, element, attributes){
      // Initialise the nowshowing variable to show the first image.
      scope.nowShowing = 0;

      // Set an interval to show the next image every couple of seconds.
      $interval(function showNext(){
        // Make sure we loop back to the start.
        if(scope.nowShowing != scope.images.length - 1){
          scope.nowShowing ++;
        }
        else{
          scope.nowShowing = 0;
        }
      }, 2000);

      // Image click behaviour
      scope.openInNewWindow = function(index){
        $window.open(scope.images[index].url);
      }
    }
  };
})

Vous verrez que j'ai utilisé un isolate scope pour rendre cette directive réutilisable et pour garder les choses bien séparées. Vous n'êtes pas obligé de le faire, mais c'est une bonne pratique. Le html de la directive doit donc également passer les images que vous souhaitez mettre dans la galerie, comme ceci:

index.html

  <body ng-controller="AppController">
    <div gallery-example="" images="imageList"></div>
  </body>

Donc, le dernier bit de javascript que nous devons écrire est de remplir ce tableau d'images dans la portée AppController. Normalement, vous utiliseriez un service pour obtenir une liste d'images à partir d'un serveur ou quelque chose, mais dans ce cas, nous allons le coder en dur:

.controller('AppController', function($scope){
  $scope.imageList = [
    {
      url: 'http://placekitten.com/200/200',
      name: 'Kitten 1'
    },
    {
      url: 'http://placekitten.com/201/201',
      name: 'Kitten 2'
    },
    {
      url: 'http://placekitten.com/201/202',
      name: 'Kitten 3'
    },
    {
      url: 'http://placekitten.com/201/203',
      name: 'Kitten 4'
    }
  ]
})

Enfin, le style. Cela définira également l'animation (notez l'utilisation de ng-hide classes etc). Je vous recommande fortement lisez ceci ici car c'est un sujet trop grand pour être couvert dans cette réponse (déjà longue!):

.fade-animation.ng-hide-add,
.fade-animation.ng-hide-remove {
  -webkit-transition:0.5s linear all;
  -moz-transition: 0.5s linear all;
  -o-transition: 0.5s linear all;
  transition:0.5s linear all;

  display:block !important;
  opacity:1;
}

Ceci est votre résultat final

24
Ed Hinchliffe

J'ai eu ce problème au cas où j'utilisais des alias d'angularJS. Si j'ai écrit quelque chose comme ça:

function someController($scope) {
    var vm = this;

    vm.switchSelected = function (passedEvent) {
    }
}

puis si dans le code html pour écrire ce qui suit:

<div ng-controller="toolBoxController as tbc">

puis pour utiliser switchSelected, vous devez écrire quelque chose comme ceci:

<img ng-src="{{si}}" width="230px" ng-click="tbc.switchSelected($event)"/>

alors, vérifiez avez-vous utilisé

 var vm=this;

dans votre contrôleur. Ensuite, vous devez ajouter un alias à votre partie html.

0
Yuriy Zaletskyy

J'ai fini par envelopper chaque image avec un lien et en changeant jQuery de manière appropriée. C'était le plus rapide et le plus facile pour moi.

<a href="url" target="_blank">
   <img class="commercial" ng-src="pathToImageOrImageVar"/>
</a>

Et changé de ligne

var backImg = $('.commercial-container img:first');

changé en

var backImg = $('.commercial-container a:first');
0
trainoasis