更改路线后多次调用Angular服务功能

时间:2019-07-29 20:38:55

标签: angular angular-services angular8

我有一个8号角项目。它具有复制数据的服务功能。当我复制数据并转到另一页时,如果我再次回到同一页面并再次复制数据,它将复制两次数据。如果我再次执行此操作,它将多次调用服务功能并多次复制数据。

我尝试了许多不同的方法,但是它仍然多次复制数据。希望你能理解我的要求。我正在等待您的答案和解决方案。

这是我的app.module.ts代码;

import { APP_BASE_HREF } from '@angular/common';
import { NgModule } from '@angular/core';
import { ModuleWithProviders } from '@angular/compiler/src/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app';

import { CategoryComponent } from './views/category';

import { CategoryService } from './services/category';

@NgModule({
    declarations: [
        AppComponent,
        CategoryComponent
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        ReactiveFormsModule.withConfig({ warnOnNgModelWithFormControl: 'never' }),
        HttpClientModule
    ],
    providers: [{ provide: APP_BASE_HREF, useValue: '/AngularProject/' }, CategoryService ],
    bootstrap: [AppComponent]
})
export class AppModule { }

这是我的服务代码;

import { Injectable } from "@angular/core";
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ICategory } from '../models/ICategory';

@Injectable({ providedIn: 'root' })
export class CategoryService {
    private linkIndex: string = "Ajax/Category/Index";
    private linkCopy: string = "Ajax/Category/Copy";

        constructor(private http: HttpClient) {
    }

    getIndex(): Observable<Array<ICategory>> {
        return this.http.get<Array<ICategory>>(this.linkIndex);
    }

    getCopy(id: string): Observable<boolean> {
        let params = new HttpParams().set("id", id);
        return this.http.get<boolean>(this.linkCopy, { params: params });
    }
}

这是我的CategoryComponent代码;

import { Component, OnDestroy, OnInit } from "@angular/core";
import { Subscription } from "rxjs";
import { Router } from "@angular/router";
import { CategoryService } from "../../services/category";
import * as $ from "jquery";

@Component({
    templateUrl: './index.html'
})

export class CategoryComponent implements OnInit, OnDestroy {
    errorMsg: string;
    CategoryList: any;

    callTable: boolean;

    private subscription: Subscription = new Subscription();

    constructor(private service: CategoryService, private router: Router) {
    }

    ngOnInit() {
        this.callTable = true;
        this.FillData();
    }

    FillData() {
        if (this.callTable == true) {
            this.subscription = this.service.getIndex().subscribe((answer) => {
                this.CategoryList = answer;
                this.callTable = false;

                setTimeout(() => {
                    $(".data-table").dataTable({
                        "bJQueryUI": true,
                        "sPaginationType": "full_numbers",
                        "sDom": '<""l>t<"F"fp>'
                    });

                    $(document).on("click", "a.cpyLink", function () {
                        $(this).addClass("active-cpy");
                        $("a.cpy-yes").attr("data-id", $(this).attr("data-id"));
                    });

                    $(document).on("click", "a.cpy-yes", () => {
                        let id: string = $("a.cpy-yes").attr("data-id");
                        this.onCopy(id);
                    });
                }, 1);
            }, resError => this.errorMsg = resError, () => { this.subscription.unsubscribe(); });
        }
    }

    ngOnDestroy(): void {
        this.subscription.unsubscribe();
    }

    onCopy(id) {
        this.subscription = this.service.getCopy(id).subscribe((answer) => {
            if (answer == true) {
                let currentUrl = this.router.url;
                this.router.navigate(['/'], { skipLocationChange: true }).then(() => { this.router.navigate([currentUrl]) });
            }
        }, resError => this.errorMsg = resError, () => { this.subscription.unsubscribe(); });
    }
}

1 个答案:

答案 0 :(得分:3)

通常,您应避免将Angular和jQuery混合使用。在这里,您的特定问题是由于在ngOnInit中调用System.Deployment.Application.InvalidDeploymentException (HashValidation) - Application manifest has either a different computer has than the one specified or no has at all - Source: System.Deployment 而引起的。由于ngOnInit每次您路由到页面时都会调用,因此this.FillData()中的代码会在您每次路由时被调用。

由于this.FillData()被重复调用,因此,每次您路由到页面时,每次都将事件处理程序附加到jQuery(数据表和onclicks)中。由于您在路由时永远不会分离事件处理程序,因此最终会多次附加同一事件。由于您在文档级别附加了处理程序并使用event bubbling,在文档级别附加了多个处理程序,因此每次添加一个新的处理程序时,情况就变得更糟了。额外的时间。

由于您正在使用DataTables,因此建议您完全删除jQuery代码,并将处理程序转换为正确的Angular方法。有很多类似DataTables的组件(例如,我广泛使用了ag-grid)。

如果必须使用jQuery(无论出于何种原因),则需要重构代码以在路由到组件或从组件路由时删除任何现有的事件处理程序。可以肯定的是,您只可以在其中粘贴this.FillData()

.off('click')

或者您需要确保仅在父组件中一次附加事件处理程序(因为无论如何都将其冒泡)。