AngularJS - $ scope变量未在工厂中更新

时间:2015-07-28 12:42:37

标签: javascript angularjs webrtc

使用ONSIP.JS api与webRTC进行视频通话。 在我的角度应用程序中,我创建了一个VideoSupport工厂。

当通过用户操作调用函数时,$ scope vars会在DOM中更新。 但是,当通过侦听我的RTC会话对象来触发函数时,DOM不会改变任何东西。

当我在我的控制器而不是工厂中制作原型时,我可以通过在setStatus函数中调用$ scope。$ apply来解决问题。但这在工厂是不可能的。

所以例子: 我解雇了sendInvite函数 - >邀请按钮被禁用..这有效。

当对方接听电话时,"接受"功能里面 setSession被调用。 由最后一个操作改变的每个变量都不会反映在我的DOM中。所有按钮都保持禁用状态。

控制器:

function SupportController($scope, $stateParams, navigationService, $css, VideoSupportFactory) {

    $scope.VideoSupport = VideoSupportFactory;
    $scope.VideoSupport.createUA();

}

厂:

function VideoSupportFactory($modal) {
    var remoteMedias = angular.element( document.querySelector( '#remote-media' ) );
    var remoteMedia = remoteMedias[0];

    return {
        disableTerminate: true,
        disableAccept: true,
        disableInvite: false,
        _volume: 50,
        mute:false,

        createUA: function (credentials) {
            if (credentials !== null && typeof credentials === 'object') {
                this.ua = new SIP.UA(credentials);
                this.ua.on('invite', this.handleInvite.bind(this));
            } else {
                this.ua = new SIP.UA();
            }
        },

        handleInvite: function (session) {
            if (this.session) {
                session.reject();
                return;
            }

            this.setSession(session);
            this.disableAccept = false;
        },

        acceptSession: function () {
            if (!this.session) {
                return;
            }

            this.disableAccept = true;
            this.session.accept(remoteMedia);
        },

        sendInvite: function () {
            var session = this.ua.invite('test123@behousing.onsip.com', remoteMedia);
            this.setSession(session);
            this.disableInvite = true;
        },

        setSession: function (session) {
            session.on('progress', function () {
                progressSound.play();
                this.setStatus('progress', true);
            }.bind(this));

            session.on('accepted', function () {
                console.log(session);
                progressSound.pause();
                this.setStatus('accepted', true);
            }.bind(this));

            session.on('failed', function () {
                progressSound.pause();
                this.openModal('sm', 'Oops!', 'The connection could not be established...');
                this.setStatus('failed', false);
                delete this.session;
            }.bind(this));

            session.on('bye', function () {
                this.setStatus('bye', false);
                delete this.session;
            }.bind(this));

            session.on('refer', session.followRefer(function (req, newSession) {
                this.setStatus('refer', true);
                this.setSession(newSession);
            }.bind(this)));

            this.session = session;
        },

        setStatus: function (status, disable) {
            this.mainClass = status;
            this.disableInvite = disable;
            this.disableTerminate = !disable;
            //$scope.$apply();
        },

        terminateSession: function () {
            if (!this.session) {
                return;
            }

            progressSound.pause();
            this.setStatus('bye', false);
            this.session.terminate();
        },

        sendDTMF: function (tone) {
            if (this.session) {
                this.session.dtmf(tone);
            }
        },

        volume: function (newVolume) {
            if (arguments.length) {
                console.log('Setting volume:', newVolume, parseInt(newVolume, 10));
                remoteMedia.volume = (parseInt(newVolume, 10) || 0) / 100;
                return (this._volume = newVolume);
            } else {
                return this._volume;
            }
            ;
        },

        toggleMute: function () {
            if (!this.session) {
                return;
            }

            if (this.mute) {
                this.session.unmute();
                this.mute = false;
            } else {
                this.session.mute();
                this.mute = true;
            }

        },

        openModal: function (size, title, text) {
            var modalInstance = $modal.open({
                animation: true,
                templateUrl: 'SupportModalContent.html',
                controller: 'SupportModalInstanceCtrl',
                size: size,
                resolve: {
                    title: function () {
                        return title;
                    },
                    text: function () {
                        return text;
                    }
                }
            });
        }

    }
}

1 个答案:

答案 0 :(得分:0)

不确定这是否是正确的方法,但你可以尝试观察者模式,我刚刚在下面放了一个变量:

    setStatus: function (status, disable) {
        this.mainClass = status;
        this.disableInvite = disable;
        this.disableTerminate = !disable;
        //$scope.$apply();
        this.notifyObservers();
    },
    observers: [],
    notifyObservers: function(){
        this.observers.forEach(function(notifyFn){
            notifyFn();
        });
    },
    addObserver: function(notifyFn){
        this.observers.push(notifyFn);
    }


    ...
    // in controller

    $scope.VideoSupport = VideoSupportFactory;
    $scope.VideoSupport.createUA();
    $scope.VideoSupport.addObserver(update);
    function update(){
        $scope.$apply();
    }

当然,最简单的黑客可能只是看一些参数:

$scope.$watch('VideoSupport.mainClass', function() {
    console.log('status changed');
});