我正在创建一个页面,用户可以在其中插入多个文本区域。每个文本区域都应该具有基本的文本编辑器(粗体和斜体)。
为此,我选择了CKEditor。问题在于,每次创建文本区域时,我都必须这样做:
ClassicEditor.create(document.querySelector(newCKEditorId), {
toolbar: [ 'bold', 'italic' ],
});
要创建多个实例,我正在使用Vue.js,如下所示:
<div v-for="(linha, index) in lista_de_pessoas">
<div :id="index" v-html="linha.componentes"></div>
</div>
我使用v-html
是因为组件的html标签将来自数据库(是的,我知道这不是一个好主意)。
由于我需要对组件列表中的每个textarea组件使用不同的ID,因此我创建了以下方法:
getNumeroDeLinhas() {
return $('#lista_de_ementas .lista .row').length + 1;
},
initNewCKEditor(id_componente) {
ClassicEditor.create(document.querySelector(newCKEditorId), {
toolbar: [ 'bold', 'italic' ],
});
},
addComponentes() {
let newCKEditorId = 'ementa_' + this.getNumeroDeLinhas();
let linha = {
componentes:
'<div class="row" style="margin: 0px;">' +
'<div class="input-field col s12">' +
'<textarea name="content" id="'+ newCKEditorId + '">ementa_' + newCKEditorId + '_da_disciplina</textarea>' +
'<label for="ementa_' + newCKEditorId + '" class="active">Ementa ' + newCKEditorId +'</label>' +
'</div>' +
'</div>',
id: '#' + newCKEditorId
}
this.lista_de_ementas.push(linha);
}
它返回给我:
Uncaught (in promise) TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at qa.init (datacontroller.js:253)
at qa.<anonymous> (observablemixin.js:254)
at qa.fire (emittermixin.js:207)
at qa.<computed> [as init] (observablemixin.js:258)
at classiceditor.js:206
因为调用initNewCKEditor()
时html元素尚未呈现。为了解决这个问题,我在Vue中添加了一个watch:{}
:
watch:{
lista_de_ementas:function(val){
this.initNewCKEditor(val[val.length -1].id);
}
但是它仍然会返回相同的错误。
我的问题是:为什么即使在调用watch函数时仍未呈现该元素,我该如何解决呢?还有另一种方法吗?
这是我的完整代码:
HTML
<!DOCTYPE html>
<html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-ckeditor2"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<script src="https://code.jquery.com/jquery-3.4.0.js"></script>
<body class="grey lighten-4">
<main style="padding:20px">
<!-- Lista de Ementas -->
<div id="lista_de_ementas">
<div class="white z-depth-1 u-default">
<h5 style="margin-bottom: 20px">Ementa da diciplina</h5>
<div class="lista">
<div v-for="item in lista_de_ementas">
<div v-html="item.componentes"></div>
</div>
</div>
<!-- Btn Adicionar -->
<button class="btn" v-on:click="addComponentes()"><i class="material-icons left">add</i>Adicionar</button>
</div>
</div>
<!-- Lista de Ementas -->
</main>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="https://cdn.ckeditor.com/ckeditor5/12.1.0/classic/ckeditor.js"></script>
<!-- COMPONENTES VUE -->
<script src="js/lista_de_ementas.js"></script>
lista_de_emendas.js
new Vue({
el: '#lista_de_ementas',
data: {
lista_de_ementas: []
},
watch:{
lista_de_ementas:function(val){
this.initNewCKEditor(val[val.length -1].id);
}
},
methods: {
getNumeroDeLinhas() {
return $('#lista_de_ementas .lista .row').length + 1;
},
initNewCKEditor(newCKEditorId) {
ClassicEditor.create(document.querySelector(newCKEditorId), {
toolbar: [ 'bold', 'italic' ],
});
},
addComponentes() {
let newCKEditorId = 'ementa_' + this.getNumeroDeLinhas();
let linha = {
componentes:
'<div class="row" style="margin: 0px;">' +
'<div class="input-field col s12">' +
'<textarea name="content" id="'+ newCKEditorId + '">ementa_' + newCKEditorId + '_da_disciplina</textarea>' +
'<label for="ementa_' + newCKEditorId + '" class="active">Ementa ' + newCKEditorId +'</label>' +
'</div>' +
'</div>',
id: '#' + newCKEditorId
}
this.lista_de_ementas.push(linha);
}
},
mounted() {
this.addComponentes()
}
});