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

标签 javascript angularjs webrtc

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

当通过用户操作调用函数时,$scope 变量会在 DOM 中更新。 然而,当通过监听我的 RTC session 对象来触发一个函数时,DOM 没有改变任何东西。

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

举个例子: 我启动了 sendInvite 函数 -> 邀请按钮被禁用了。这有效。

当对方接听电话时,里面的“accepted”函数 setSession 被调用。 最后一个操作更改的每个变量都不会反射(reflect)在我的 DOM 中。所有按钮都保持禁用状态。

Controller :

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;
                    }
                }
            });
        }

    }
}

最佳答案

不确定这样做是否正确,但您可以尝试观察者模式,我在下面放了一个变体:

    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();
    }

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

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

关于javascript - AngularJS - $scope 变量未在工厂中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31676659/

相关文章:

angularjs - 如何在MVC中创建文件并向其中插入json数据

javascript - 如何比较 ng-repeat. 中的值?

javascript - 网络音频 API : efficiently play a PCM stream

javascript - 使用 PHP 和 Ajax 将文件上传到 Google Cloud Storage Bucket

javascript - JavaScript 中的递归归约

javascript - 一个接一个地加载脚本

javascript - 如何包含特定于每个 View 的javascript文件angularjs

javascript - 更改时返回选定的值,取消选择时不重复

javascript - 服务器在WebRTC聊天室中的作用是什么?

javascript - 实时网络音频输入可以在 Ubuntu 上的 Google Chrome 中使用吗?