Laravel Livewire中Summernote/CKEditor无法显示内容问题求助
问题描述
基于Laravel Livewire开发员工乘车证明模板编辑器时,遇到WYSIWYG文本框(Summernote/CKEditor)无法加载已保存内容的问题:用户选择模板类型后,数据库中存储的模板内容始终无法显示在编辑器中,文本框保持为空,更换两款编辑器后问题依旧。核心需求是实现模板类型选择后自动加载对应已保存内容,支持编辑修改。
相关代码
组件模板代码
<div> <div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800"> <label class="block text-sm"> <span class="text-gray-700 dark:text-white">{{__('site.team_member_document.document_type')}}</span> <select class="block w-full mt-1 text-sm" name="team_member_document_type_id" id="team_member_document_type_id" wire:model="team_member_document_type_id" wire:change="onChangeDocumentType()"> <option value="">{{__('site.team_member_document.select_document_type')}}</option> @foreach($document_types as $item) <option value="{{$item['id']}}" @if(old('team_member_document_type_id')==$item['id']) selected @endif >{{$item['name']}}</option> @endforeach </select> </label> <label class="block text-sm" wire:ignore> <span class="text-gray-700 dark:text-white">{{__('site.team_member_document.template')}}</span> <textarea name="template" id="template" wire:model.defer="template">{{ $template }}</textarea> </label> <label class="block mt-4 text-sm"> <button type="button" wire:click="submitForm()" class="px-4 py-2 text-sm font-medium"> {{__('site.save')}} </button> <a href="{{route('team_member_document.index')}}" class="px-4 py-2 text-sm font-medium"> {{__('site.cancel')}} </a> </label> </div> <script> $(function () { $('#template').summernote({ placeholder: '', height: 300, toolbar: [ ['style', ['style']], ['font', ['bold', 'underline', 'clear']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], ['insert', ['link']], ['view', ['fullscreen', 'codeview']] ], callbacks: { onChange: function (contents, $editable) { @this.set('template', contents); } } }); }) </script>
Livewire组件代码
namespace App\Http\Livewire; use Livewire\Component; class TeamMemberDocumentTemplate extends Component { public $document_types; public $team_member_document_type_id; public $template; protected array $rules = [ 'template' => 'required|min:30', ]; public function mount($document_types) { $this->template = ''; $this->document_types = $document_types; } public function render() { return view('livewire.team-member-document-template'); } public function onChangeDocumentType() { $this->template = $this->document_types->filter(function ($item) { return ($this->team_member_document_type_id == $item->id); })->first()->template ?? ''; } public function submitForm() { $this->validate(); $document_type = $this->document_types->filter(function ($item) { return ($this->team_member_document_type_id == $item->id); })->first(); $document_type->update([ 'template' => $this->template ]); return redirect()->route('team_member_document.index'); } }
解决方案
问题核心是Livewire更新template属性后,WYSIWYG编辑器未同步接收新内容,需通过事件监听和手动赋值实现双向同步。
1. 前端监听Livewire属性更新,同步编辑器内容
修改组件模板的JS代码,添加Livewire事件监听,当template属性变化时手动更新Summernote内容:
<script> $(function () { // 初始化编辑器并保存实例 const editor = $('#template').summernote({ placeholder: '', height: 300, toolbar: [ ['style', ['style']], ['font', ['bold', 'underline', 'clear']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], ['insert', ['link']], ['view', ['fullscreen', 'codeview']] ], callbacks: { onChange: function (contents, $editable) { @this.set('template', contents); } } }); // 监听Livewire自定义事件,同步编辑器内容 @this.on('templateUpdated', () => { editor.summernote('code', @this.template); }); // 初始化时加载初始内容(若存在) const initialContent = @json($template); if (initialContent) { editor.summernote('code', initialContent); } }) </script>
2. Livewire组件触发更新事件
修改onChangeDocumentType方法,设置template后触发自定义事件通知前端更新编辑器:
public function onChangeDocumentType() { $selected = $this->document_types->filter(function ($item) { return ($this->team_member_document_type_id == $item->id); })->first(); $this->template = $selected->template ?? ''; // 触发事件通知前端同步编辑器 $this->dispatch('templateUpdated'); }
3. CKEditor适配方案
若使用CKEditor,逻辑完全一致,仅需将编辑器初始化和内容同步代码替换为CKEditor的API:
<script> ClassicEditor .create(document.querySelector('#template')) .then(editor => { // 监听编辑器内容变化,同步到Livewire editor.model.document.on('change:data', () => { @this.set('template', editor.getData()); }); // 监听Livewire事件,同步内容到编辑器 @this.on('templateUpdated', () => { editor.setData(@this.template); }); // 初始化加载内容 const initialContent = @json($template); if (initialContent) { editor.setData(initialContent); } }); </script>
关键注意事项
- 确保编辑器容器标签上的
wire:ignore属性正确,避免Livewire干扰编辑器DOM结构 - 使用
@json($template)传递内容,避免HTML转义导致的格式错乱 - 双向同步需同时处理:编辑器内容变化同步到Livewire,Livewire属性变化同步到编辑器
内容的提问来源于stack exchange,提问作者mrakodol
相关产品推荐
相关产品推荐

