You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alpine.js x-text未随变量更新:Laravel+WebRTC相机状态显示异常

问题原因

你直接修改了独立的data对象,而不是Alpine.js组件的响应式状态。Alpine不会跟踪组件上下文之外的普通对象变化,所以即便data.isOpen被设为true,UI也不会更新。

修复方案

1. 绑定Alpine组件到DOM

在根元素添加x-data="componentData()",让Alpine初始化并跟踪组件状态:

<div class="card" x-data="componentData()">
    <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>

2. 重构JavaScript逻辑

将相机检测函数移入组件内部,使用Alpine的响应式上下文更新状态,并通过init()生命周期方法触发检测:

@push('extra_js')
<script>
    function componentData() {
        return {
            isOpen: false,
            cameraClasses() {
                console.log("isOpen:", this.isOpen);
                return {
                    '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() {
                this.$refs.examForm.submit();
            },
            async openMediaDevices(constraints) {
                try {
                    const stream = await navigator.mediaDevices.getUserMedia(constraints);
                    if (stream) {
                        console.log(stream);
                        this.isOpen = true;
                        console.log(this.isOpen);
                    }
                    return stream;
                } catch (error) {
                    console.error('Error accessing media devices.', error);
                    return null;
                }
            },
            init() {
                this.openMediaDevices({ video: true });
            }
        }
    }
</script>
@endpush

修复原理

  • x-data="componentData()"让Alpine接管组件状态,通过代理监听isOpen的变化
  • 相机检测函数内部使用this.isOpen更新响应式状态,Alpine会自动同步到UI
  • init()方法在组件加载时自动触发相机检测,替代全局window.onload更贴合组件生命周期

内容的提问来源于stack exchange,提问作者Laxmidhar Maharana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 22:50:02