Я использую Laravel с Alpinejs и webRTC, чтобы проверить, включена ли у пользователя камера или нет. Часть webRTC работает нормально и обнаруживает камеру. Но значение x-text, которое показывает, включена или выключена камера, не обновляется после получения потока webRTC.
<div class = "card">
<div class = "card-header font-bold">Preparation Page</div>
<div class = "card-body">
{!! $exam->bo_exam_instruction !!}
<div class = "mt-2">
Camera : <span x-text = "isOpen ? 'On' : 'Off'" class = "badge" :class = "cameraClasses()"></span>
</div>
<div>
<form action = "{{ route('student.startOlympiad', $exam->id) }}" method = "POST"
x-ref = "examForm">
@csrf
<button class = "btn mt-2" :class = "buttonClasses()"
x-on:click.prevent = "confirmStartExam()">
Start Exam</button>
</form>
</div>
</div>
</div>
@push('extra_js')
<script>
function componentData() {
return {
isOpen: false,
cameraClasses() {
console.info("isOpen:", this.isOpen);
return {
// <span class = "badge badge-danger">Danger</span>
'badge-danger': !this.isOpen,
'badge-success': this.isOpen
}
},
adapter: {
browserDetails: {
browser: navigator.userAgent,
version: navigator.appVersion
}
},
buttonClasses() {
return {
'btn-primary': !this.isOpen,
'btn-secondary': this.isOpen
};
},
confirmStartExam() {
if (this.isOpen) {
Swal.fire({
title: 'Are you sure?',
text: 'Once you start the exam, you cannot go back!',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, start the exam!'
}).then((result) => {
if (result.isConfirmed) {
this.startExam();
}
});
} else {
Swal.fire({
title: 'Camera Permission!',
text: 'Please allow camera permissions',
icon: 'info',
})
}
},
startExam() {
// Submit the form using Alpine.js
this.$refs.examForm.submit();
},
}
}
const data = componentData();
async function openMediaDevices(constraints) {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
// If stream is obtained, set isOpen to true
if (stream) {
console.info(stream); //gets stream
data.isOpen = true;
console.info(data.isOpen); //comes true
}
return stream;
} catch (error) {
console.error('Error accessing media devices.', error);
return null;
}
}
window.onload = async function() {
await openMediaDevices({
video: true
});
console.info("Final isOpen:", data.isOpen);
}
</script>
@endpush
когда data.isOpen = true; x-text="isOpen ? 'On' : 'Off'" должно отображаться «ON». все еще показывает "ВЫКЛ"
Данные компонента инкапсулированы внутри этого компонента, поэтому вы не можете напрямую редактировать isOpen
снаружи компонента, как вы пытаетесь это сделать.
Вы можете использовать событие для связи с вашим компонентом, но почему бы просто не переместить функцию openMediaDevices
на сам компонент? Затем вы можете вызвать его из функции init()
компонента и изменить значение this.isOpen
оттуда:
function componentData() {
return {
isOpen: false,
// ... other properties and methods
async openMediaDevices(constraints) {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
if (stream) {
this.isOpen = true;
}
return stream;
} catch (error) {
console.error('Error accessing media devices.', error);
return null;
}
},
async init() {
await this.openMediaDevices({
video: true,
});
console.info('Final isOpen:', this.isOpen);
},
};
}