为了使用 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/