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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:46:07