使用 Jquery 函数调用 Angular 2

Using Jquery function call with Angular 2

我正在尝试在我的 Angular 2 应用程序中使用此 convForm jquery 插件。

我已经在编辑 angular.json 文件的项目中成功安装了 jquery 和 convForm。

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 

在angular中如何像例子一样调用回调函数?

什么等同于:

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

jQuery 插件需要一个全局回调,即。一一 window 对象。在示例中,它们声明的回调只是 <script> 中的顶级函数,因此它们将位于 window 中。 您在 angular 组件的 class 中声明的方法将在每个组件实例上,因此不是全局可用的,即。 jQuery 插件不会 看到 它。

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

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

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

另外,请注意 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 组件 class 将不再使用,很快就会被垃圾回收,因此您是否显式删除该组件并不重要this.convForm参考。

但只有那些 DOM 元素将被删除,其中 Angular 知道。 Angular 只知道在组件模板中定义并由 Angular 呈现的 DOM,但它不知道您通过 [= 添加到 DOM 的内容65=],所以它不会删除那些。 运气好的话,jQuery插件只在angular组件下添加了DOM元素,所以移除组件后,jQuery插件的DOM元素是也删除了。

但是 jQuery 插件可能在 DOM 树的顶部添加了一些东西,可能在 angular 应用程序之外(对话框和其他弹出窗口通常有效像这样),并且当 angular 组件被销毁时,它不会被删除。

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