在 Angular 2 中使用 Jquery 函数调用

Posted

技术标签:

【中文标题】在 Angular 2 中使用 Jquery 函数调用【英文标题】:Using Jquery function call with Angular 2 【发布时间】:2020-05-19 09:16:16 【问题描述】:

我正在尝试在我的 Angular 2 应用程序上使用这个 convForm jquery 插件。

我已成功将 jquery 和 convForm 安装到我的项目中,编辑 angular.json 文件。

在plugin example中,他们有回调函数,它们的html字段在属性下:data-callback

我不明白如何在 angular 组件中使用这些回调函数,因为回调不使用打字稿调用函数。

conv-form.html

<div id="chat" class="conv-form-wrapper">
    <form action="/" method="post" class="hidden" onsubmit="event.preventDefault()">
         <input type="number" data-callback="amount"
              data-conv-question="What is the amount you like ?" name="amount"
              data-pattern="^[0-9]*$">
    </form>
 </div>

conv-form.ts

import  Component, OnInit  from '@angular/core';
declare let $: any;

@Component(
    selector: 'app-conv-form',
    templateUrl: './conv-form.component.html',
    styleUrls: ['./conv-form.component.scss']
)
export class ConvFormComponent implements OnInit 
    ngOnInit() 
          let convForm = $('#chat').convform( selectInputStyle: 'disable' );
    

    amount(stateWrapper, ready) 
    if(stateWrapper.current.answer.value.length > 0)
        ready();
    
  

呈现此问题时,我收到错误消息:

Uncaught TypeError: window[convState.current.input.callback] is not a function
at Object.onInputSubmit 

如何像示例一样调用回调函数,但使用角度?

相当于:

<script>
    function google(stateWrapper, ready) 
        window.open("https://google.com");
        ready();
    
</script>

【问题讨论】:

【参考方案1】:

jQuery 插件需要一个全局回调,即。一个是窗口对象。在示例中,他们声明的回调只是 &lt;script&gt; 中的***函数,因此它们将显示在窗口上。 您在 Angular 组件的类中声明的方法将位于每个组件实例上,因此无法全局使用,即。 jQuery 插件不会看到它。

我真的反对混合使用 jQuery 和 Angular,因为这总是会导致很大的黑客攻击,但我想你还是会这样做,所以这里有一个可能的解决方案。我没有任何 angular+jQuery 项目,所以无法测试解决方案,但我希望它有所帮助。

因此,您必须将对您的组件实例的方法之一的引用放到窗口中,这样它才能在全局范围内可用,但会指向您的组件实例。请参阅下面的扩展 ngOnInit。还要注意bind,它是能够在amount 方法中使用this 来访问角度组件所必需的。

另外请注意,如果您在页面上多次显示ConvFormComponent,它们会干扰,可能只有最后一个回调会起作用。如果需要多个,则需要引入一种机制,使globalAmountCb 对于每个ConvFormComponent 实例都是唯一的。

另外,请注意ngOnDestroy,一旦组件被拆除,我在其中删除了回调,您还应该拆除/关闭/退出 jQuery convForm 事物。

<div id="chat" class="conv-form-wrapper">
    <form action="/" method="post" class="hidden" onsubmit="event.preventDefault()">
         <input type="number" data-callback="globalAmountCb"
              data-conv-question="What is the amount you like ?" name="amount"
              data-pattern="^[0-9]*$">
    </form>
 </div>
import  Component, OnInit, OnDestroy  from '@angular/core';
declare let $: any;
declare window: any;

@Component(
    selector: 'app-conv-form',
    templateUrl: './conv-form.component.html',
    styleUrls: ['./conv-form.component.scss']
)
export class ConvFormComponent implements OnInit, OnDestroy 
    ngOnInit() 
        // note the `globalAmountCb` name in the template above too
        window.globalAmountCb = this.amount.bind(this).
        let convForm = $('#chat').convform( selectInputStyle: 'disable' );
    

    ngOnDestroy() 
        window.globalAmountCb = undefined;
        // also maybe tear down the `convForm` thing
    

    amount(stateWrapper, ready) 
    if(stateWrapper.current.answer.value.length > 0)
        ready();
    
  

更新:说明为何需要清理以及可能需要进行何种清理。

当你离开这个页面时,angular组件类将不再被使用,并且很快就会被垃圾回收,所以你显式删除this.convForm引用也没关系。

但是只有那些 DOM 元素会被移除,Angular 知道这些元素。 Angular 只知道在组件模板中定义并由 Angular 渲染的 DOM,但它不知道您通过 jQuery 添加到 DOM 中的内容,因此它不会删除这些内容。 如果幸运的话,jQuery插件只在angular组件下添加了DOM元素,所以当组件被移除时,jQuery插件的DOM元素也会被移除。

但可能是 jQuery 插件在 DOM 树的顶部添加了一些东西,可能在 Angular 应用程序之外(对话框和其他弹出框通常像这样工作),并且当 Angular组件被销毁。

如果 jQuery 插件提供了某种清理机制来删除它们,你必须查看它。

【讨论】:

拆掉convForm这个东西,是不是指使用:this.convForm = undefined @helloworld 添加了对答案的响应 从这个对应关系来看,似乎是一个附加到 convForm 的销毁函数:github.com/eduardotkoller/convForm/issues/22

以上是关于在 Angular 2 中使用 Jquery 函数调用的主要内容,如果未能解决你的问题,请参考以下文章

一旦 HTML 在 Angular 4 中完全动态呈现,如何在 jQuery 中调用函数?

Angular 2 从 Jquery 调用 Typescript 函数会导致未捕获的 TypeError

Angular 5 和 jQuery:(点击)不调用函数

强制 Angular 在 JQLite 上使用 jQuery

使用 Jquery Ajax 后,Angular 函数突然不起作用

jQuery $.map 的 Angular 等价物?