Angular 2+ TypeError: $(...).magnificPopup不是一个函数。

3

我找不到关于在 Angular 中使用 Magnific Popup 的任何信息。问题是,jQuery 无法识别 Magnific Popup。

相比之下,我使用了 jquery-confirm,它可以正常工作。与 Magnific Popup 相同的处理过程,唯一不同的是调用方法,即 $.confirm({jquery-confirm stuff})

angular-cli.json

...    
"scripts": [
            "../node_modules/jquery/dist/jquery.js",
            "../node_modules/magnific-popup/dist/jquery.magnific-popup.min.js",
            "../node_modules/bootstrap/dist/js/bootstrap.js",
...

package.json

...
  "googleapis": "19.0.0",
    "jquery": "3.2.1",
    "jquery-confirm": "^3.3.2",
    "magnific-popup": "^1.1.0",
    "moment": "2.18.1",
...

Ts

import * as $ from "jquery";
...
setTimeout(()=>{
            $(document).ready(function($){
                alert();
                $('.popupImage').magnificPopup({
                    type: 'image'
                    // other options
                    ,
                });
            });

        },2000)

2
不要使用Angular和jQuery的组合。永远不要这样做。jQuery不知道Angular在DOM中生成了什么,而Angular也不知道jQuery在做什么。使用Angular或jQuery,但不要同时使用两者。 - Jeremy Thille
4
@JeremyThille - 我不同意(在这个情况下)。这个特定的 工具 是一个用于打开图像的UI工具,它依赖于jquery。我认为这没有问题。如果问题涉及DOM或数据操作,我会同意你的观点。 - Igor
关于您的代码的注释:不要使用 $(document).ready(,而是使用 Angular 生命周期钩子 - Igor
@Igor 这个工具是一个 jQuery 插件。它需要 jQuery,这意味着它不应该在 Angular 应用程序中使用。我坚持我的立场。相同的工具/功能可能已经存在于 Angular 模块中,如果不存在,必须自定义制作。但是_不要使用 jQuery_。jQuery 和 Angular 是对立的,彼此陌生,这会导致笨拙和难以维护的代码,更不用说你必须加载两个库而不是一个。 - Jeremy Thille
1
现实世界的开发。你以为我整天在做什么?织毛衣吗?好吧,那就继续加载两个互不知晓对方在做什么的库吧,祝你好运 :) - Jeremy Thille
显示剩余5条评论
3个回答

8
为了使这个工作起来,我采用了以下步骤:

我使用cli创建了一个新项目 ng new ng-magnific-popup 我运行了 npm install --save jquery magnific-popup 我更新了 app.component.html

`<a #img href="assets/BingWallpaper-2018-03-23.jpg">img</a>`

我更新了app.component.ts
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';

import * as $ from 'jquery';
import 'magnific-popup';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild('img') imgElement: ElementRef;

  ngAfterViewInit(): void {
    $(this.imgElement.nativeElement).magnificPopup({ type: 'image' });
  }
}

我也更新了.angular-cli.json文件,通过将"../node_modules/magnific-popup/dist/magnific-popup.css"添加到样式数组中,包含他们的css文件。
完整代码请查看GitHub repo

1
我会将其标记为解决方案,因为它回答了问题。使用本地元素是答案:D 但对于每个img使用viewchild不实用,而是使用class选择器..如果img标签是动态的呢?例如:相册照片。仅供参考,我现在使用fancybox..它有npm,搜索fancybox npm..而且没有任何问题。很好。 - david valentino

0
你可以尝试这个:
import $ from "jquery";
import 'magnificPopup'; // <=== if it exist into your node_module folder

否则,将其导入到您的index.html中。

0

谢谢peinearydevelopment! 但是对我来说,AfterViewChecked起作用了,但不知何故AfterViewInit没有。

import { Component, OnInit, AfterViewChecked  } from '@angular/core';
import * as $ from 'jquery';
import 'magnific-popup';


@Component({templateUrl: 'home.component.html'})
export class HomeComponent implements AfterViewChecked   {
    @ViewChild('img')   imgElement:ElementRef; 
    @ViewChild('video') videoElement:ElementRef; 

    ngAfterViewChecked (): void {
   
        if (this.imgElement) {
           $(this.imgElement.nativeElement).magnificPopup({ type: 'image' });
        }

        if (this.videoElement) {
            $(this.videoElement.nativeElement).magnificPopup({ type: 'iframe' });
         }
 
    }  
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接