简体   繁体   English

Typescript服务在angularjs controller中多次订阅,无法退订

[英]Typescript service subscribed multiple times in angularjs controller and not able to unsubscribe it

Scenario: I need to merge angularjs with angular so currently I have started creating components and services and using them with angularjs controller.场景:我需要将 angularjs 与 angular 合并,所以目前我已经开始创建组件和服务并将它们与 angularjs controller 一起使用。

Angularjs Controller is initiated from $routeProvider. Angularjs Controller 从$routeProvider发起。

I have created a component of card view which shows card grid layout with images and have buttons to do approve/reject content of card view.我创建了一个卡片视图组件,它显示带有图像的卡片网格布局,并有按钮来批准/拒绝卡片视图的内容。 Clicking on approve/reject button shows md-dialog pop-up to add message and other thing.单击批准/拒绝按钮会显示 md-dialog 弹出窗口以添加消息和其他内容。

In typescript service I have created function to get and set data to show pop-up accordingly.在 typescript 服务中,我创建了 function 来获取和设置数据以相应地显示弹出窗口。

Clicking on component button calls typescript service which sets data and in angularjs controller I have subscribed to service get function.单击组件按钮调用设置数据的 typescript 服务,在 angularjs controller 我已经订阅了服务,得到 function。

Here are 2 issues I am facing:这是我面临的两个问题:

  1. Whenever page loads the service gets subscribed, so for eg: suppose I have opened that page 3 times, service get subscribed 3 times.每当页面加载时,服务都会被订阅,例如:假设我打开该页面 3 次,服务就会被订阅 3 次。 So when I click on component button it shows md-dialog pop-up 3 times.因此,当我单击组件按钮时,它会显示 3 次 md-dialog 弹出窗口。

  2. When I tried to unsubscribe the service on load and subscribe again, it never gets subscribed and pop-up doesn't shows up.当我尝试在加载时取消订阅服务并再次订阅时,它永远不会被订阅并且不会显示弹出窗口。

Here is code of typescript service:这是typescript服务的代码:

import { BehaviorSubject, Observable } from 'rxjs';
import * as angular from 'angular';

class CardClickDTO {
    event;
    item;
    type: string;
}

let app = angular.module('PortalApp');
app.factory('contentcardSrv', [function (): {} {

    let cs = this;

    // Observable for Click Content
    cs._cardClickModel$ = new BehaviorSubject(new CardClickDTO());
    cs.CardClcikModel$ = cs._cardClickModel$.asObservable();

    // get data
    cs.getOnContentClickData = new Observable<CardClickDTO>(() => {
        return cs.CardClcikModel$;
    });

    // set data
    cs.setOnContentClick = (event, item, type: string): void => {
        let co: CardClickDTO = new CardClickDTO();
        if (type == "reset") // to reset Observable
            cs._cardClickModel$.next(co);
        else {
            co.event = event;
            co.item = item;
            co.type = type;
            cs._cardClickModel$.next(co);
        }
    };

    return {
        setOnContentClick: cs.setOnContentClick,
        getOnContentClickData: cs.getOnContentClickData,
    };
}]);

AngularJS Controller AngularJS Controller

import { portal } from '../portal';
import { saveAs } from 'file-saver';

portal.controller('controller', ['$scope', '$http', '$window', '$mdDialog', '$location', '$cookies', '$mdSidenav', '$mdToast', '$timeout', '$mdpTimePicker', '$interpolate', 'Map', '$sce', '$filter', 'menuSv', 'contentcardSrv', 'permissionSrv', '$anchorScroll', 
    function ($scope, $http, $window, $mdDialog, $location, $cookies, $mdSidenav, $mdToast, $timeout, $mdpTimePicker, $interpolate, Map, $sce, $filter, menuSv, contentcardSrv, permissionSrv, $anchorScroll) {

 // subscribed to get data function of service
 contentcardSrv.getOnContentClickData().subscribe((co) => {
            if (co != undefined && co.event != undefined && co.item != null && co.item != undefined && co.type != "" && co.type != undefined) {
                $scope.onContentClick(co.event, co.item, co.type);
                co.event.stopPropagation();
            }
        });

 $scope.onContentClick = function (ev, item, type) {
     // show md-dialog pop-up.
     };
}]);

contentcard.component.ts内容卡.component.ts

//import angular from 'angular';
import { portal } from 'js/portal';

portal.component('contentcardComponent', {
    templateUrl: './contentcard.component.html',
    controllerAs: 'ctrl',
    controller: 'contentcardComponentController',
    bindings: {
        itemsdata: '@',
        viewdata: '@'
    }
});

portal.controller('contentcardComponentController', ['contentcardSrv',
    function (contentcardSrv): void {

        const ctrl = this;

        // component click function
        ctrl.onContentClick = function (ev, item, type: string): void {
            if (type == "Approved" || type == "Rejected" || type == "Partial" || type == "ApproveMessage")
                ctrl.btnClicked = true;
            contentcardSrv.setOnContentClick(ev, item, type); // set data service function
        };
    }]);

Solved the problem by using $destroy event of angularjs.通过使用 angularjs 的 $destroy 事件解决了这个问题。

In AngularJS Controller在 AngularJS Controller

let onContentClickSubscription = contentcardSrv.getOnContentClickData().subscribe((co) => {
        if (co != undefined && co.event != undefined && co.item != null && co.item != undefined && co.type != "" && co.type != undefined) {
            $scope.onContentClick(co.event, co.item, co.type);
            co.event.stopPropagation();
        }
    });

$scope.$on('$destroy', function iVeBeenDismissed() {
            // say goodbye to your controller here
            // release resources, cancel request...
            onContentClickSubscription.unsubscribe();
        })

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

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