如何在 alpine 中初始化异步函数?

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

我目前正在开发我们的 capstone 项目,该项目在 laravel 上运行作为我的框架,以 tailwind 作为我的 css,我偶然发现了一个我仍然无法理解的错误。

这是我的代码的第 1 块,它在可搜索的下拉列表中显示我的数据库中活动的校园:

<div class="flex-grow">
    <label for="campus" class="block mb-2 text-sm font-medium">Campus</label>
    <div x-data="selectAcademic()" x-init="fetchCampuses()" class="w-full flex flex-col items-center relative">
        <div class="w-full">
            <div @click.away="close()" class="p-1 bg-white flex border border-gray-300 rounded-lg">
                <input
                    id="campus"
                    x-model="filter"
                    @click="open()"
                    x-transition:leave="transition ease-in duration-100"
                    x-transition:leave-start="opacity-100"
                    x-transition:leave-end="opacity-0"
                    @keydown.enter.stop.prevent="selectCampusOption()"
                    @keydown.arrow-up.prevent="focusPrevCampusOption()"
                    @keydown.arrow-down.prevent="focusNextCampusOption()"
                    class="p-1 px-2 appearance-none outline-none w-full text-gray-800"
                    placeholder="Select Campus"
                    x-bind:value="selectedCampusName()">
                <div class="text-gray-300 w-8 py-1 pl-2 pr-1 border-l flex items-center border-gray-300">
                    <button @click="toggle()" class="cursor-pointer w-6 h-6 text-gray-600 outline-none focus:outline-none">
                        <svg  xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                            <polyline x-show="!isOpen()" points="18 15 12 20 6 15"></polyline>
                            <polyline x-show="isOpen()" points="18 15 12 9 6 15"></polyline>
                        </svg>

                    </button>
                </div>
            </div>
        </div>
        <div x-show="isOpen()" class="my-2 absolute shadow bg-white top-100 z-40 w-full lef-0 rounded max-h-select overflow-y-auto svelte-5uyqqj">
            <div class="flex flex-col w-full">
                <template x-for="(campusOption, index) in filteredCampusOptions()" :key="index">
                <div @click="onOptionCampusClick(index)" :class="classCampusOption(campusOption.campus, index)" :aria-selected="focusedCampusOptionIndex === index">
                    <div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-facilityEaseSecondary hover:bg-blue-200">
                        <div class="w-full items-center flex">
                            <div class="mx-2 -mt-1"><span x-text="campusOption.campus"></span>
                            </div>
                        </div>
                    </div>
                </div>
                </template>
            </div>
        </div>
    </div>
    @if($errors->has('campus'))
        <div class="text-facilityEaseSecondary font-bold italic text-xs">{{ $errors->first('campus') }}</div>
    @endif
</div>

这是块 2,其中当用户在块 1 上选择特定校园时,该块应依赖于在块 1 上选择的 ID:

<div class="flex-grow">
    <label for="college" class="block mb-2 text-sm font-medium">College</label>
    <div x-data="selectAcademic()" x-init="fetchColleges($)" class="w-full flex flex-col items-center relative">
        <div class="w-full">
            <div @click.away="close()" class="p-1 bg-white flex border border-gray-300 rounded-lg">
                <input
                    id="college"
                    x-model="filter"
                    @click="open()"
                    x-transition:leave="transition ease-in duration-100"
                    x-transition:leave-start="opacity-100"
                    x-transition:leave-end="opacity-0"
                    @keydown.enter.stop.prevent="selectCollegeOption()"
                    @keydown.arrow-up.prevent="focusPrevCollegeOption()"
                    @keydown.arrow-down.prevent="focusNextCollegeOption()"
                    class="p-1 px-2 appearance-none outline-none w-full text-gray-800"
                    placeholder="Select College"
                    x-bind:value="selectedCollegeName()">
                <div class="text-gray-300 w-8 py-1 pl-2 pr-1 border-l flex items-center border-gray-300">
                    <button @click="toggle()" class="cursor-pointer w-6 h-6 text-gray-600 outline-none focus:outline-none">
                        <svg  xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                            <polyline x-show="!isOpen()" points="18 15 12 20 6 15"></polyline>
                            <polyline x-show="isOpen()" points="18 15 12 9 6 15"></polyline>
                        </svg>
                    </button>
                </div>
            </div>
        </div>
        <div x-show="isOpen()" class="my-2 absolute shadow bg-white top-100 z-40 w-full lef-0 rounded max-h-select overflow-y-auto svelte-5uyqqj">
            <div class="flex flex-col w-full">
                <template x-for="(collegeOption, index) in filteredCollegeOptions()" :key="index">
                <div @click="onOptionCollegeClick(index)" :class="classCollegeOption(collegeOption.college, index)" :aria-selected="focusedCollegeOptionIndex === index">
                    <div class="flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative hover:border-facilityEaseSecondary hover:bg-blue-200">
                        <div class="w-full items-center flex">
                            <div class="mx-2 -mt-1"><span x-text="collegeOption.college"></span>
                            </div>
                        </div>
                    </div>
                </div>
                </template>
            </div>
        </div>
    </div>
    @if($errors->has('college'))
    <div class="text-facilityEaseSecondary font-bold italic text-xs">{{ $errors->first('college') }}</div>
    @endif
</div>

现在,块 2 没有显示任何内容。后端可以工作,虽然我可以无缝获取我的数据,但它不会显示在我的视图上。

这里是处理此操作方法的 javascript 文件:

function selectAcademic() {
    return {
        filter: '',
        show: false,
        selected: null,
        focusedCampusOptionIndex: null,
        focusedCollegeOptionIndex: null,
        campusOptions: null,
        collegeOptions: null,
        selectedCampusID: null,
        computed: {
            selectedCampus() {
                return this.selected ? this.selected.campus : this.filter;
            },
            selectedCampusId: {
                get() {
                    return this.selected ? this.selected.id : 0;
                },
                set(campusID) {
                    if (this.selected) {
                        this.selected.id = campusID;
                    }
                }
            },
        },

        close() {
            this.show = false;
            this.focusedCampusOptionIndex = this.selected ? this.focusedCampusOptionIndex : null;
            this.focusedCollegeOptionIndex = this.selected ? this.focusedCollegeOptionIndex : null;
        },

        open() {
            this.show = true;
            this.filter = '';
        },

        toggle() {
            if (this.show) {
                this.close();
            } else {
                this.open()
            }
        },

        isOpen() { return this.show === true },

        selectedCampusName() { return this.selected ? this.selected.campus : this.filter; },

        selectedCollegeName() { return this.selected ? this.selected.college : this.filter; },

        classCampusOption(id, index) {
            const isSelected = this.selected ? (id == this.selected.campus) : false;
            const isFocused = (index == this.focusedCampusOptionIndex);
            return {
            'cursor-pointer w-full border-gray-100 border-b hover:bg-blue-50': true,
            'bg-blue-100': isSelected,
            'bg-blue-50': isFocused
            };
        },

        classCollegeOption(id, index) {
            const isSelected = this.selected ? (id == this.selected.college) : false;
            const isFocused = (index == this.focusedCollegeOptionIndex);
            return {
            'cursor-pointer w-full border-gray-100 border-b hover:bg-blue-50': true,
            'bg-blue-100': isSelected,
            'bg-blue-50': isFocused
            };
        },

        async fetchCampuses() {
            console.log('Fetching Campus options...');
            await fetch('/getCampuses')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response.json();`enter code here`
                })
                .then(data => {
                    console.log('Campus data:', data);
                    this.campusOptions = data;
                })
                .catch(error => {
                    console.error('Error fetching campus data:', error);
                });
        },

        async fetchColleges(selectedCampusID) {
            selectedCampusID = this.selectedCampusId;

            console.log('Fetching colleges by campus...');
            console.log('Fetching colleges for Campus: ', selectedCampusID);

            await fetch(`/getCollegesByCampus/${selectedCampusID}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response.json();
                })
                .then(data => {
                    console.log('College data:', data);
                    this.collegeOptions = data;
                })
                .catch(error => {
                    console.error('Error fetching college data:', error);
                });
        },

        filteredCampusOptions() {
            if (!this.campusOptions) {
                return [];
            }
            console.log('Displaying filtered campus options: ', this.campusOptions);
            return this.campusOptions.filter(campusOption => {
                return campusOption && campusOption.campus && campusOption.campus.toLowerCase().indexOf(this.filter) > -1;
            });
        },

        filteredCollegeOptions() {
            if (!this.collegeOptions) {
                return [];
            }
            console.log('Displaying filtered college options:', this.collegeOptions);
            return this.collegeOptions.filter(collegeOption => {
                return collegeOption && collegeOption.college && collegeOption.college.toLowerCase().indexOf(this.filter) > -1;
            });
        },

        async onOptionCampusClick(index) {
            this.focusedCampusOptionIndex = index;
            await this.selectCampusOption();
            await this.fetchColleges();
            await this.filteredCollegeOptions();
        },

        async onOptionCollegeClick(index) {
            this.focusedCollegeOptionIndex = index;
            this.selectCollegeOption();
        },

        async selectCampusOption() {
            if (!this.isOpen()) {
                return;
            }
            this.focusedCampusOptionIndex = this.focusedCampusOptionIndex ?? 0;
            const selected = this.filteredCampusOptions()[this.focusedCampusOptionIndex]
            if (this.selected && this.selected.campus == selected.campus) {
                this.filter = '';
                this.selected = null;
                this.selectedCampusId = null;
            }
            else {
                this.selected = selected;
                this.selectedCampusId = selected.id;
                console.log('Selected:', this.selected);
                console.log('Selected Campus ID:', this.selectedCampusId);
                // await this.fetchColleges();
                // await this.filteredCollegeOptions();
            }
            this.close();
        },

        selectCollegeOption() {
            if (!this.isOpen()) {
                return;
            }
            this.focusedCollegeOptionIndex = this.focusedCollegeOptionIndex ?? 0;
            const selected = this.filteredCollegeOptions()[this.focusedCollegeOptionIndex]
            if (this.selected && this.selected.college == selected.college) {
                this.filter = '';
                this.selected = null;
            }
            else {
                this.selected = selected;
            }
            this.close();
        },

        focusPrevCampusOption() {
            if (!this.isOpen()) {
                return;
            }
            const optionsNum = Object.keys(this.filteredCampusOptions()).length - 1;
            if (this.focusedCampusOptionIndex > 0 && this.focusedCampusOptionIndex <= optionsNum) {
                this.focusedCampusOptionIndex--;
            }
            else if (this.focusedCampusOptionIndex == 0) {
                this.focusedCampusOptionIndex = optionsNum;
            }
        },

        focusPrevCollegeOption() {
            if (!this.isOpen()) {
                return;
            }
            const optionsNum = Object.keys(this.filteredCollegeOptions()).length - 1;
            if (this.focusedCollegeOptionIndex > 0 && this.focusedCollegeOptionIndex <= optionsNum) {
                this.focusedCollegeOptionIndex--;
            }
            else if (this.focusedCollegeOptionIndex == 0) {
                this.focusedCollegeOptionIndex = optionsNum;
            }
        },

        focusNextCampusOption() {
            const optionsNum = Object.keys(this.filteredCampusOptions()).length - 1;
            if (!this.isOpen()) {
                this.open();
            }
            if (this.focusedCampusOptionIndex == null || this.focusedCampusOptionIndex == optionsNum) {
                this.focusedCampusOptionIndex = 0;
            }
            else if (this.focusedCampusOptionIndex >= 0 && this.focusedCampusOptionIndex < optionsNum) {
                this.focusedCampusOptionIndex++;
            }
        },

        focusNextCollegeOption() {
            const optionsNum = Object.keys(this.filteredCollegeOptions()).length - 1;
            if (!this.isOpen()) {
                this.open();
            }
            if (this.focusedCollegeOptionIndex == null || this.focusedCollegeOptionIndex == optionsNum) {
                this.focusedCollegeOptionIndex = 0;
            }
            else if (this.focusedCollegeOptionIndex >= 0 && this.focusedCollegeOptionIndex < optionsNum) {
                this.focusedCollegeOptionIndex++;
            }
        },
    }
}

Console Screenshot to see if fetchColleges() work

PS:我刚刚开始了解 alpine.js,代码是我从以下链接获得的模板:https://codepen.io/dixie0704/pen/jOVxGXL

这些是我期望在视图中看到的数据,我直接播种这些值以查看它是否会显示:

        ['collegeID' => 2, 'college' => 'College of Technology', 'dean' => 'Ruvel J. Cuasito', 'status' => 1, 'created_by' => 'Administrator-Seeder', 'created_at' => $currentTimestamp, 'updated_at' => $currentTimestamp],
        ['collegeID' => 2, 'college' => 'College of Engineering and Architecture', 'dean' => 'Lory Liza D. Bulay-Og', 'status' => 1, 'created_by' => 'Administrator-Seeder', 'created_at' => $currentTimestamp, 'updated_at' => $currentTimestamp],
        ['collegeID' => 2, 'college' => 'College of Science and Mathematics', 'dean' => 'Maria Luisa B. Salingay', 'status' => 1, 'created_by' => 'Administrator-Seeder', 'created_at' => $currentTimestamp, 'updated_at' => $currentTimestamp],
        ['collegeID' => 2, 'college' => 'College of Science and Technology Education', 'dean' => 'Grace S. Pimentel', 'status' => 1, 'created_by' => 'Administrator-Seeder', 'created_at' => $currentTimestamp, 'updated_at' => $currentTimestamp],
        ['collegeID' => 2, 'college' => 'College of Information Technology and Computing', 'dean' => 'Love Jhoye M. Raboy', 'status' => 1, 'created_by' => 'Administrator-Seeder', 'created_at' => $currentTimestamp, 'updated_at' => $currentTimestamp],
        ['collegeID' => 2, 'college' => 'Senior High School Department', 'dean' => 'Kristiane Pagurayan', 'status' => 1, 'created_by' => 'Administrator-Seeder', 'created_at' => $currentTimestamp, 'updated_at' => $currentTimestamp]
javascript laravel asynchronous tailwind-css alpine.js
1个回答
0
投票

其实我现在明白我的问题了。我从来没有理解过 alpine.js。更多的是代码的理论方面。我试图让它做一些不应该做的事情。这是我的错误。

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