简体   繁体   English

AngularJS:点击img? 用jQuery操纵图像(类似于画廊)?

[英]AngularJS: ng-click on img? Manipulating images (kind of gallery-like) with jQuery?

Should ng-click work with img tag ? ng-click是否可以使用img标签?

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

myFunction is defined in controller and is $scope available … Nothing gets called; myFunction在控制器中定义,并且$ scope可用...没有任何东西被调用; any ideas? 有任何想法吗?

(I would like to open a new tab/window when image is clicked, but I don't even get into my function) (我想在点击图像时打开一个新的标签/窗口,但我甚至没有进入我的功能)

Thanks for any info 谢谢你的任何信息

EDIT I probably rushed myself when first asking this question. 编辑我在第一次提出这个问题时可能会匆匆忙忙。 I know now why it doesn't work in my case: I am manipulating images with jQuery for some kind a 'gallery' effect … (if anyone has an idea how to do that in AngularJS please bring it on). 我现在知道为什么它在我的情况下不起作用:我使用jQuery操纵图像以获得某种“画廊”效果......(如果有人知道如何在AngularJS中执行此操作请将其启用)。 This is the html I am talking about: 这是我正在谈论的HTML:

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

And here the jQuery with which I create fade-in/fade-out effect (showing one image, then the next and so on indefinitely) 在这里我使用jQuery创建淡入/淡出效果(显示一个图像,然后是下一个等等,无限期)

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

So my real question is this: 所以我真正的问题是:

  • How can I get the same behaviour as with my jQuery so that images will be ng-clickable? 我怎样才能获得与jQuery相同的行为,以便图像可以点击?

You can of course provide a better solution (perhaps AngularJS one) for changing images like this if you know one … 你当然可以提供一个更好的解决方案(也许是AngularJS)来改变这样的图像,如果你知道一个......

Thank you 谢谢

Yes, ng-click works on images. 是的, ng-click适用于图像。

Without further code I can't tell you why yours isn't working, but the code you have pasted will call myFunction in the scope of the controller governing that element. 如果没有进一步的代码,我无法告诉你为什么你的代码没有工作,但你粘贴的代码将在控制该元素的控制器范围内调用myFunction

EDIT 编辑

You definitely don't need to use jQuery for this, and it's not really thinking about it in an "angular" mindset if you do. 你绝对不需要为此使用jQuery,如果你这样做,它并没有真正考虑它的“角度”思维模式。

My suggestion is to make a directive to do this. 我的建议是做一个指令来做到这一点。 I've created a plunker with a simple example of what it could look like. 创建了一个带有简单示例的plunker

Here's a summary: 这是一个总结:

Note: Because animation is important to you, make sure you include the ng-animate src and include it as a dependency in your app module definition. 注意:由于动画对您很重要,因此请确保包含ng-animate src并将其作为依赖项包含在应用程序模块定义中。 Use the same version of animate as base angular. 使用相同版本的animate作为基本角度。

HTML 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 使用Javascript

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

Now Define a template for your directive: 现在为您的指令定义模板:

galleryPartial.html 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>

This template simply says "I want one image for every item listed in the 'images' array from the scope. The src is should be the url property of the image, and the alt text should be the name. When I click an image, run the openInNewWindow function passing the index of that image in the array. Finally, hide images unless the nowShowing variable is set to their index." 这个模板只是简单地说“我希望从范围内'images'数组中列出的每个项目都有一个图像src应该是图像的url属性, alt文本应该是名称。当我点击图像时,运行openInNewWindow函数,传递数组中该图像的索引。最后,隐藏图像,除非将nowShowing变量设置为它们的索引。“

Also note the class fade-animation . 还要注意类fade-animation This could be called anything, but this is the class we'll use to define the animation in CSS later. 这可以被称为任何东西,但这是我们稍后将用于在CSS中定义动画的类。

Next we write the directive itself. 接下来我们编写指令本身。 It's pretty simple - it just has to use this template, and then define the openInNewWindow function, as well as iterate nowShowing through the array indexes: 它非常简单 - 它只需要使用这个模板,然后定义openInNewWindow函数,以及迭代nowShowing数组索引:

.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);
      }
    }
  };
})

You will see I have used an isolate scope to make this directive reusable and to keep things separated nicely. 你会看到我已经使用了一个隔离范围来使这个指令可以重复使用并保持良好的分离。 You don't have to do this, but it's good practice. 你不必这样做,但这是一个很好的做法。 The html for the directive must therefore also pass the images you want to put in the gallery, like so: 因此,指令的html也必须传递您想要放入图库的图像,如下所示:

index.html 的index.html

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

So the last bit of javascript we need to write is to populate that images array in the AppController scope. 因此,我们需要编写的最后一点javascript是在AppController范围中填充该图像数组。 Normally you'd use a service to get a list of images from a server or something, but in this case we'll hard code it: 通常,您使用服务从服务器或其他东西获取图像列表,但在这种情况下,我们将对其进行硬编码:

.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'
    }
  ]
})

Finally, styling. 最后,造型。 This will also define the animation (note the use of ng-hide classes etc). 这也将定义动画(注意使用ng-hide类等)。 I strongly recommend you read up on this here as it is too big a subject to cover in this (already long!) answer: 我强烈建议你在这里阅读,因为这个(已经很久!)答案中的主题太大了:

.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;
}

This is your end result 这是你的最终结果

EDIT Since as you said in the comments bootstrap is not an option for you, i would suggest you write your own little directive. 编辑因为正如你在评论中所说bootstrap不适合你,我建议你写自己的小指令。 There is probably tons of tutorial out there like this 有可能是吨教程有像这样


The Problem in your case is, that you manipulate the DOM from outside the Angular-Scope. 在您的情况下,问题是,您从Angular-Scope外部操作DOM。 So Angular iteslf doesnt even know about those new image-elements, and further not about the ng-click and ng-src directive. 因此,Angular iteslf甚至不知道那些新的图像元素,而且还不了解ng-click和ng-src指令。 This would only be the case, if you would use Angulars own $compile-Service to put the images back into the DOM. 如果您使用Angulars自己的$ compile-Service将图像放回DOM中,情况就是这样。

I would recommend you to use Angular-UI Bootstrap for an image gallery. 我建议你使用Angular-UI Bootstrap作为图片库。 Else, you would need to create your own Directive for this, but why reinvent the wheel? 否则,您需要为此创建自己的指令,但为什么要重新发明轮子?

I ended up wrapping each image with link and changing jQuery appropriately. 我最终用链接包装每个图像并适当地更改jQuery。 It was the fastest and easiest for me. 这对我来说是最快最容易的。

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

And changed line 改变了行

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

changed to 变成

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

I had this issue in case when I used aliases of angularJS. 我遇到过这个问题,以防我使用angularJS的别名。 If I wrote something like this: 如果我写了这样的话:

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

    vm.switchSelected = function (passedEvent) {
    }
}

and then if in html code to write the following: 然后如果在html代码中写下面的内容:

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

then in order to use switchSelected you need write something like this: 那么为了使用switchSelected你需要写这样的东西:

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

so, check did you used 所以,检查你使用过

 var vm=this;

in your controller. 在你的控制器中。 Then you need to add aliasing to your html part. 然后你需要为你的html部分添加别名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM