如何在Angular中将视图中的全局变量数据传递至控制器?
把视图中的全局变量传递到Angular控制器的方案
嘿,我来帮你搞定这个问题。首先得说,直接在视图里用全局变量其实不太符合Angular的设计思路,但如果是现有代码要改造,或者你想先快速实现,我给你两种方案:一种是快速适配现有代码的,另一种是更符合Angular最佳实践的封装方式。
方案1:直接访问全局变量(快速但不推荐)
你定义的dataUri和videoData是全局变量,它们挂载在浏览器的window对象上,所以在Angular控制器里可以直接通过window.dataUri来访问。不过要注意一个关键问题:这些变量是在videojs的录制逻辑完成后才会有值,所以控制器不能在初始化时直接拿,得等数据准备好。
可以在videojs的录制回调里,手动触发Angular的$digest循环,或者用$rootScope.$broadcast发送一个事件,让控制器监听:
步骤1:修改视图里的script
<script> var player = videojs("myVideo", { controls: true, width: 320, height: 240, fluid: false, plugins: { record: { audio: true, video: true, maxLength: 100, debug: true } } }, function(){ videojs.log('Using video.js', videojs.VERSION, 'with videojs-record', videojs.getPluginVersion('record')); // 监听录制完成事件 this.on('finishRecord', function() { // 这里拿到录制后的dataUri和videoData window.dataUri = this.recordedData; window.videoData = this.recordedBlob; // 获取Angular的$rootScope,触发事件 var $rootScope = angular.element(document.body).injector().get('$rootScope'); $rootScope.$apply(function() { $rootScope.$broadcast('videoRecorded', { dataUri: window.dataUri, videoData: window.videoData }); }); }); }); </script>
步骤2:在控制器里监听事件
angular.module('myApp').controller('VideoController', function($scope) { $scope.videoRecordData = {}; // 监听录制完成的事件 $scope.$on('videoRecorded', function(event, data) { $scope.videoRecordData.dataUri = data.dataUri; $scope.videoRecordData.videoData = data.videoData; // 现在数据已经在控制器的scope里了,可以用它做后续操作 }); });
这个方法能快速适配你现有的代码,但依赖全局变量和手动触发Angular的digest,不是最佳实践,长期维护容易出问题。
方案2:封装成Angular指令(推荐,符合Angular架构)
更好的方式是把videojs的录制逻辑封装成一个Angular指令,这样可以完全避免全局变量,直接通过双向绑定把数据传给控制器。
步骤1:创建指令
angular.module('myApp').directive('videoRecorder', function() { return { restrict: 'E', scope: { recordedData: '=' // 双向绑定,把录制结果传给控制器的变量 }, template: '<video id="myVideo" class="video-js vjs-default-skin"></video>', link: function(scope, element, attrs) { // 初始化videojs播放器 var player = videojs(element.find('video')[0], { controls: true, width: 320, height: 240, fluid: false, plugins: { record: { audio: true, video: true, maxLength: 100, debug: true } } }, function() { videojs.log('Using video.js', videojs.VERSION, 'with videojs-record', videojs.getPluginVersion('record')); // 监听录制完成事件 this.on('finishRecord', function() { // 把录制数据通过双向绑定传给控制器 scope.$apply(function() { scope.recordedData = { dataUri: this.recordedData, videoData: this.recordedBlob }; }.bind(this)); }); }); // 销毁指令时销毁播放器,避免内存泄漏 scope.$on('$destroy', function() { if (player) { player.dispose(); } }); } }; });
步骤2:在视图里使用指令
<video-recorder recorded-data="videoRecordData"></video-recorder>
步骤3:在控制器里直接使用数据
angular.module('myApp').controller('VideoController', function($scope) { $scope.videoRecordData = {}; // 当录制完成后,$scope.videoRecordData会自动更新 $scope.$watch('videoRecordData', function(newVal) { if (newVal.dataUri) { // 这里可以处理录制好的数据,比如上传、预览等 console.log('录制完成,数据已传到控制器:', newVal); } }, true); });
这个方案完全遵循Angular的设计模式,没有全局变量,代码更模块化,容易维护和测试。
内容的提问来源于stack exchange,提问作者Viral Patel
相关产品推荐
相关产品推荐

