为什么我的脚本 运行 AJAX 没有刷新?
Why does my script not run on AJAX refresh?
我正在为我的项目开发头像上传器。到目前为止一切都很好,今天早上我没有遇到任何问题。过了一会儿,砰。死亡和毁灭。很伤心。
当我第一次选择一个文件时,它会立即弹出裁剪工具,而且效果很好。如果我尝试上传不同的文件,裁剪工具就会消失,甚至不会显示图像预览。
我的系统如何工作?我使用 Laravel 框架作为我的后端,并使用 Laravel Livewire 包作为前端功能。 Livewire 允许我在 PHP.
中编写类似 Vue 的组件
这是我正在处理的表格。每次 Livewire 在输入中看到新文件时,它也是刷新的组件。
<label for="image-upload">
<div class="w-full mt-4 button"><i class="far fa-fw fa-upload"></i> Drag and drop, or <b>browse</b></div>
</label>
<input id="image-upload" type="file" wire:model="image" class="hidden" accept="image/png, image/gif, image/jpeg">
@if($image)
<div id="avatar-preview" class="w-full" style="height: 300px;"></div>
<script>
new Croppie(document.querySelector('#avatar-preview'), {
viewport: { width: 200, height: 200, type: 'circle' },
enforceBoundary: true,
}).bind('{!! $image->temporaryUrl() !!}');
</script>
<button type="submit" class="w-full mt-16 button is-green">Submit new avatar</button>
@endif
我正在使用裁剪工具的 Croppie JS 包。它要求我向它传递一个它将附加到的 img
元素,或者传递一个适合的容器。我选择了一个容器,这样我就可以控制裁剪工具的大小。当我将图像上传到输入时,Livewire 将获取图像,验证它是图像并且没有通过特定大小,然后将图像上传到临时目录。 $image->temporaryUrl()
回显该临时文件的路径。文件上传完成且临时图像准备就绪后,Livewire 仅通过 AJAX 刷新组件。此时,我尝试创建一个新的 Croppie 实例,将其附加到我的预览容器,并将临时图像绑定到它。
这适用于第一个文件上传!然后,当我尝试更改文件(作为用户可能)时,整个实例都消失了。我尝试检查并查看再次实例化 Croppie 是否有问题,因为在我看来,如果组件已刷新,则创建该工具的新实例应该不是问题。
<script>
if (typeof crop === 'undefined') {
console.log('crop undefined');
let crop = new Croppie(document.querySelector('#avatar-preview'), {
viewport: { width: 200, height: 200, type: 'circle' },
enforceBoundary: true,
}).bind('{!! $image->temporaryUrl() !!}');
} else {
console.log('crop defined');
crop.bind('{!! $image->temporaryUrl() !!}');
}
console.log('crop finished');
</script>
'undefined' 和 'finished' 日志在第一次上传时出现,但刷新时没有任何反应。
所以我也测试了这样做...
@if($image)
<img src="{{ $image->temporaryUrl() }}">
@endif
至少要确保预览工作正常,你看吧!
最大的问题是,即使 Croppie 不刷新,也不会出现错误或警告。它似乎根本不执行 <script>
标记中的内容。
有什么提示或建议吗?
进一步阅读后,Livewire 似乎可以从组件 class 发出可以被 JavaScript 拾取的“事件”。我的问题是由 .innerHtml
.
更改 DOM 内容的自然行为引起的
在我的组件 class 中,在处理输入更新时要执行的操作的 updated()
函数中,我添加了
$this->emit('avatar_preview_updated', $this->image->temporaryUrl());
然后我将此侦听器添加到我页面的全局 JS:
livewire.on('avatar_preview_updated', image => {
new Croppie(document.querySelector('#avatar-preview'), {
url: image,
viewport: { width: 200, height: 200, type: 'circle' },
boundary: { height: 300 },
enforceBoundary: true,
});
});
这会产生所需的结果。
我正在为我的项目开发头像上传器。到目前为止一切都很好,今天早上我没有遇到任何问题。过了一会儿,砰。死亡和毁灭。很伤心。
当我第一次选择一个文件时,它会立即弹出裁剪工具,而且效果很好。如果我尝试上传不同的文件,裁剪工具就会消失,甚至不会显示图像预览。
我的系统如何工作?我使用 Laravel 框架作为我的后端,并使用 Laravel Livewire 包作为前端功能。 Livewire 允许我在 PHP.
中编写类似 Vue 的组件这是我正在处理的表格。每次 Livewire 在输入中看到新文件时,它也是刷新的组件。
<label for="image-upload">
<div class="w-full mt-4 button"><i class="far fa-fw fa-upload"></i> Drag and drop, or <b>browse</b></div>
</label>
<input id="image-upload" type="file" wire:model="image" class="hidden" accept="image/png, image/gif, image/jpeg">
@if($image)
<div id="avatar-preview" class="w-full" style="height: 300px;"></div>
<script>
new Croppie(document.querySelector('#avatar-preview'), {
viewport: { width: 200, height: 200, type: 'circle' },
enforceBoundary: true,
}).bind('{!! $image->temporaryUrl() !!}');
</script>
<button type="submit" class="w-full mt-16 button is-green">Submit new avatar</button>
@endif
我正在使用裁剪工具的 Croppie JS 包。它要求我向它传递一个它将附加到的 img
元素,或者传递一个适合的容器。我选择了一个容器,这样我就可以控制裁剪工具的大小。当我将图像上传到输入时,Livewire 将获取图像,验证它是图像并且没有通过特定大小,然后将图像上传到临时目录。 $image->temporaryUrl()
回显该临时文件的路径。文件上传完成且临时图像准备就绪后,Livewire 仅通过 AJAX 刷新组件。此时,我尝试创建一个新的 Croppie 实例,将其附加到我的预览容器,并将临时图像绑定到它。
这适用于第一个文件上传!然后,当我尝试更改文件(作为用户可能)时,整个实例都消失了。我尝试检查并查看再次实例化 Croppie 是否有问题,因为在我看来,如果组件已刷新,则创建该工具的新实例应该不是问题。
<script>
if (typeof crop === 'undefined') {
console.log('crop undefined');
let crop = new Croppie(document.querySelector('#avatar-preview'), {
viewport: { width: 200, height: 200, type: 'circle' },
enforceBoundary: true,
}).bind('{!! $image->temporaryUrl() !!}');
} else {
console.log('crop defined');
crop.bind('{!! $image->temporaryUrl() !!}');
}
console.log('crop finished');
</script>
'undefined' 和 'finished' 日志在第一次上传时出现,但刷新时没有任何反应。
所以我也测试了这样做...
@if($image)
<img src="{{ $image->temporaryUrl() }}">
@endif
至少要确保预览工作正常,你看吧!
最大的问题是,即使 Croppie 不刷新,也不会出现错误或警告。它似乎根本不执行 <script>
标记中的内容。
有什么提示或建议吗?
进一步阅读后,Livewire 似乎可以从组件 class 发出可以被 JavaScript 拾取的“事件”。我的问题是由 .innerHtml
.
在我的组件 class 中,在处理输入更新时要执行的操作的 updated()
函数中,我添加了
$this->emit('avatar_preview_updated', $this->image->temporaryUrl());
然后我将此侦听器添加到我页面的全局 JS:
livewire.on('avatar_preview_updated', image => {
new Croppie(document.querySelector('#avatar-preview'), {
url: image,
viewport: { width: 200, height: 200, type: 'circle' },
boundary: { height: 300 },
enforceBoundary: true,
});
});
这会产生所需的结果。