Alpine js。变量更改时 x-text 值未更新

问题描述 投票:0回答:1

我使用 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.log("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.log(stream); //gets stream
                    data.isOpen = true;
                    console.log(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.log("Final isOpen:", data.isOpen);
        }
    </script>
@endpush

当data.isOpen = true; x-text="isOpen ? 'On' : 'Off'" 这应该显示“ON”。它仍然显示“OFF”

javascript laravel webrtc laravel-blade alpine.js
1个回答
0
投票

组件数据封装在该组件内,因此您无法像您尝试那样从组件外部直接编辑

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 is obtained, set isOpen to true
        if (stream) {
          console.log(stream); // gets stream
          this.isOpen = true;
          console.log(this.isOpen); // comes true
        }
        return stream;
      } catch (error) {
        console.error('Error accessing media devices.', error);
        return null;
      }
    },
    async init() {
      await this.openMediaDevices({
        video: true,
      });
      console.log('Final isOpen:', this.isOpen);
    },
  };
}

© www.soinside.com 2019 - 2024. All rights reserved.