Cómo actualizar el modelo de un componente personalizado cuando se cambia un rasgo.
Por fin he averiguado esto por mi cuenta y quiero compartir el resultado para quien esté pasando por esto como yo. Este código recortado crea un componente de vídeo personalizado y responsivo que soporta YouTube, Vimeo, MyVRSpot y un iframe src personalizado. He conseguido que el modelo se actualizara en el lienzo cua...
Lee la respuesta completa abajo ↓Pregunta
¡Hola! He leído y releído la documentación de GrapesJS y la referencia de API sobre cómo crear un componente personalizado y simplemente no consigo entenderlo. Inicialmente empecé intentando ampliar el componente de vídeo existente, pero luego decidí crear mi propio componente de vídeo personalizado. Estoy usando el componente de vídeo existente como guía. Mi componente se puede arrastrar al lienzo y los ajustes del componente (rasgos) se pueden activar, pero no se actualiza nada en el lienzo. Mi componente tagName es un div porque necesito un envoltorio para que el iframe interno sea sensible vía CSS. Eso en sí mismo podría ser un problema en cómo estoy añadiendo el iframe, pero no puedo avanzar lo suficiente para asegurarlo.
¡Agradezco mucho cualquier consejo que podáis darme!
Actualización de fragmento de código y trasladado al comentario final
Respuestas (1)
Por fin he averiguado esto por mi cuenta y quiero compartir el resultado para quien esté pasando por esto como yo. Este código recortado crea un componente de vídeo personalizado y responsivo que soporta YouTube, Vimeo, MyVRSpot y un iframe src personalizado. He conseguido que el modelo se actualizara en el lienzo cuando se cambia un ajuste de componente (rasgo). Espero que a alguien más le resulte útil.
(función() {
var PageBuilder = {
// ...
"BuildGrapesEditor": function() {
INICIALMENTE CARGA EL CONTENIDO GUARDADO DE LA APP EN EL EDITOR
var savedComponents = JSON.parse($("#grapes-components").val());
DEFINIR COMPONENTES PERSONALIZADOS *ANTES* DE LA INICIALIZACIÓN DE LAS UVAS (MUY IMPORTANTE) - https://grapesjs.com/docs/modules/Components.html#define-custom-component-type
TAMBIÉN AÑADIR NOMBRES DE PLUGINS EN ESTE ARRAY DEVUELTO POR MÉTODO
Plugins var = esto. GatherCustomComponents();
INICIALIZAR EL EDITOR DE UVAS
esto. GrapesEditor = grapesjs.init({
contenedor: "#cs-Grapes-Editor",
Altura: "700px",
ancho: "auto",
showOffsets: cierto,
allowScripts: cierto,
componentes: savedComponents,
style: $("#grapes-css").val(),
storageManager: {
tipo: nulo,
guardado automático: falso,
},
avoidInlineStyle: cierto,
Plugins: Plugins
});
esto. GrapesCommands = esto. GrapesEditor.Commands;
esto. GrapesPanels = esto. PanelesEditor.Grapes;
esto. GrapesBlocks = esto. GrapesEditor.BlockManager;
},
"GatherCustomComponents": function() {
var _this = esto;
COMPONENTE DE VÍDEO PERSONALIZADO
var customVideo = function(editor) {
editor. DomComponents.addType("csVideo", {
MÉTODO DE MARCO - https://grapesjs.com/docs/modules/Components.html#model
"modelo": {
Predeterminados: {
VALORES PREDETERMINADOS DEL MARCO
etiquetaNombre: "div",
Arrastrable: Cierto,
Droppable: falso,
Clases: ["CS-GJS-Video"],
Contenido: '<iframe class="gjs-no-pointer" src="https://www.youtube.com/embed/mxD7QEt85ms" frameborder="0" permite="autoplay; pantalla completa" desplazamiento="no"></iframe>' +
'<style>' +
'.cs-gjs-video {' +
'posición: relativa;' +
'margen: 5px 0px;' +
'}' +
'.cs-gjs-video:antes {' +
'contenido: "";' +
'display: block;' +
'relleno-superior: 56,25%;' +
'}' +
'.cs-gjs-video iframe {' +
'ancho: 100%;' +
'altura: 100%;' +
'posición: absoluta;' +
'top: 0px;' +
'izquierda: 0px;' +
'}' +
'</style>',
Editable: Cierto,
VALORES PREDETERMINADOS PERSONALIZADOS
Proveedor: "YouTube",
videoId: "mxD7QEt85ms",
vídeoAncho: 560,
vídeoAltura: 315,
youtubeUrl: "https://www.youtube.com/embed/",
youtubeDefaultId: "mxD7QEt85ms",
vimeoUrl: "https://player.vimeo.com/video/",
vimeoDefaultId: "22439234",
myvrspotUrl: "https://live.myvrspot.com/iframe",
myvrspotDefaultId: "vff46db9afa6d",
iframeDefaultId: 'https://www.youtube.com/embed/mxD7QEt85ms',
Loop: 0,
autoplay: 0,
Controles: 1,
color: "",
REL: 1,
modestbranding: 0,
título: 1,
Retrato: 1,
Crédito: 1
},
MÉTODO DE MARCO MARCO
"init": function(properties, options) {
RASGOS CONJUNTOS
Rasgos var = esto.RasgosObtener();
this.set("rasgos", rasgos);
HACER QUE EL PANEL DE COMPONENTES SEA ACTIVO
si (_this. GrapesEditor.Panels !== indefinido) {
_this. GrapesEditor.Panels.getButton("vistas", "open-tm").set("activo", true);
}
EVENT LISTENER PARA CAMBIOS DE RASGOS
this.listenTo(this, "change:provider", this.updateTraits);
this.listenTo(this, "change:videoId change:provider change:videoWidth change:videoHeight change:autoplay change:loop change:controls change:rel change:modestbranding change:color change:portrait change:title change:byline", this.updateModel);
},
MÉTODO PERSONALIZADO PARA ACTUALIZAR EL MODELO DE COMPONENTES - https://grapesjs.com/docs/modules/Components.html#define-custom-component-type
"updateModel": function() {
this.updateSrc();
var atributos = esto.atributos;
var modelComponent = _this. GrapesEditor.getSelected();
modelComponent.addAttributes({
"data-cs-gjs-id": modelComponent.ccid
});
modelComponent.set("content", '' +
'<iframe class="gjs-no-pointer" src="' + attributes.src + '" frameborder="0" permite="autoplay; pantalla completa" desplazamiento="no"></iframe>' +
'<style>' +
'[data-cs-gjs-id="' + modelComponent.ccid + '"] {' +
'posición: relativa;' +
'margen: 5px 0px;' +
'}' +
'[data-cs-gjs-id="' + modelComponent.ccid + '"]:before {' +
'contenido: "";' +
'display: block;' +
'padding-top: ' + ((attributes.videoHeight / attributes.videoWidth) * 100) + '%;' +
'}' +
'[data-cs-gjs-id="' + modelComponent.ccid + '"] iframe {' +
'ancho: 100%;' +
'altura: 100%;' +
'posición: absoluta;' +
'top: 0px;' +
'izquierda: 0px;' +
'}' +
'</style>' +
'');
},
MÉTODO PERSONALIZADO PARA DEVOLVER EL TRAZADO DESPLEGABLE DEL PROVEEDOR
"getProviderTrait": function() {
return {
tipo: "select",
etiqueta: "Provider",
Nombre: "Proveedor",
cambioProp: 1,
Opciones: [{
Valor: "YouTube",
nombre: "YouTube"
},
{
valor: "vimeo",
nombre: "Vimeo"
},
{
valor: "myvrspot",
nombre: "MyVRSpot"
},
{
valor: "iframe",
nombre: "Custom iframe"
}
],
};
},
MÉTODO PERSONALIZADO PARA DEVOLVER RASGOS DE YOUTUBE
"getYouTubeTraits": función() {
volver [
this.getFournidorTrait(),
{
Tipo: "texto",
etiqueta: "ID de vídeo",
nombre: "videoId",
Provisional: "Por ejemplo, mxD7QEt85ms",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Ancho de vídeo",
nombre: "videoWidth",
Provisional: "Por ejemplo, 560",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Video Height",
nombre: "videoHeight",
Provisional: "Por ejemplo, 315",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Autoplay",
Nombre: "Autoplay",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Loop",
Nombre: "Loop",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Controles",
Nombre: "Controls",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Relacionado",
Nombre: "Rel",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Modest Branding",
Nombre: "modestbranding",
cambioprop: 1
}
];
},
MÉTODO PERSONALIZADO PARA DEVOLVER RASGOS VIMEO
"getVimeoTraits": función() {
volver [
this.getFournidorTrait(),
{
Tipo: "texto",
etiqueta: "ID de vídeo",
nombre: "videoId",
Provisional: "Por ejemplo, 22439234",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Ancho de vídeo",
nombre: "videoWidth",
Provisional: "Por ejemplo, 560",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Video Height",
nombre: "videoHeight",
Provisional: "Por ejemplo, 315",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Color",
Nombre: "Color",
Provisional: "Por ejemplo, #00adef",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Autoplay",
Nombre: "Autoplay",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Loop",
Nombre: "Loop",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Retrato",
Nombre: "Retrato",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Título",
Nombre: "Título",
cambioprop: 1
},
{
Tipo: "casilla de verificación",
etiqueta: "Byline",
Nombre: "Byline",
cambioprop: 1
}
];
},
MÉTODO PERSONALIZADO PARA DEVOLVER LOS RASGOS MYVRSPOT
"getMyVRSpotTraits": función() {
volver [
this.getFournidorTrait(),
{
Tipo: "texto",
etiqueta: "ID de vídeo",
nombre: "videoId",
Provisional: "Por ejemplo, vff46db9afa6d",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Ancho de vídeo",
nombre: "videoWidth",
Provisional: "Por ejemplo, 560",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Video Height",
nombre: "videoHeight",
Provisional: "Por ejemplo, 315",
cambioprop: 1
}
];
},
MÉTODO PERSONALIZADO PARA DEVOLVER RASGOS IFRAME PERSONALIZADOS
"getIframeTraits": function() {
volver [
this.getFournidorTrait(),
{
Tipo: "texto",
etiqueta: "iframe Src URL",
nombre: "videoId",
Provisional: 'por ejemplo. https://player.vimeo.com/video/22439234?autoplay=1&loop=1&title=0&byline=0&portrait=0',
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Ancho de vídeo",
nombre: "videoWidth",
Provisional: "Por ejemplo, 560",
cambioprop: 1
},
{
Tipo: "texto",
etiqueta: "Video Height",
nombre: "videoHeight",
Provisional: "Por ejemplo, 315",
cambioprop: 1
}
];
},
MÉTODO PERSONALIZADO DE AYUDA PARA OBTENER LAS CARACTERÍSTICAS DEL PROVEEDOR SELECCIONADO
"getTraits": función() {
var provider = this.get("provider");
Rasgos var = "";
switch (provider) {
Caso "YouTube":
rasgos = esto.obténRasgosYouTube();
pausa;
Caso "Vimeo":
rasgos = esto.obtenerVimeoRasgos();
pausa;
Caso "MyVRSPOT":
rasgos = esto.obtienRascosMíVRSpot();
pausa;
Caso "iframe":
rasgos = esto.getIframeTraits();
pausa;
Por defecto:
rasgos = esto.obténRasgosYouTube();
pausa;
}
devolver rasgos;
},
MÉTODO PERSONALIZADO PARA ACTUALIZAR RASGOS EN EL CAMBIO DEL DESPLEGABLE DEL PROVEEDOR
"updateTraits": función() {
this.loadTraits(this.getTraits());
var provider = this.get("provider");
switch (provider) {
Caso "YouTube":
rasgos = esto.obténRasgosYouTube();
pausa;
Caso "Vimeo":
rasgos = esto.obtenerVimeoRasgos();
pausa;
Caso "MyVRSPOT":
rasgos = esto.obtienRascosMíVRSpot();
pausa;
Caso "iframe":
rasgos = esto.getIframeTraits();
pausa;
Por defecto:
rasgos = esto.obténRasgosYouTube();
pausa;
}
devolver rasgos;
},
MÉTODO PERSONALIZADO DE AYUDA PARA ACTUALIZAR EL IFRAME SRC CUANDO CAMBIAN LOS RASGOS
"updateSrc": function() {
var provider = this.get("provider");
switch (provider) {
Caso "YouTube":
this.set("src", this.getYouTubeSrc());
pausa;
Caso "Vimeo":
this.set("src", this.getVimeoSrc());
pausa;
Caso "MyVRSPOT":
this.set("src", this.getMyVRSpotSrc());
pausa;
Caso "iframe":
this.set("src", this.getIframeSrc());
pausa;
}
},
MÉTODO PERSONALIZADO PARA CONSTRUIR YOUTUBE IFRAME SRC
"getYouTubeSrc": function() {
var videoId = this.get("videoId");
var url = this.get("youtubeUrl");
url += videoId + "?";
URL += this.get("autoplay") ? "&autoplay=1" : "";
URL += this.get("controles") ? "" : "&controls=0&showinfo=0";
URL += this.get("loop") ? "&loop=1&playlist=" + videoId : "";
URL += this.get("rel") ? "" : "&rel=0";
URL += this.get("modestbranding") ? "&modestbranding=1" : "";
URL de retorno;
},
MÉTODO PERSONALIZADO PARA CONSTRUIR VIMEO IFRAME SRC
"getVimeoSrc": function() {
var videoId = this.get("videoId");
var url = this.get("vimeoUrl");
url += videoId + "?";
URL += this.get("autoplay") ? "&autoplay=1" : "";
URL += this.get("loop") ? "&loop=1" : "";
URL += this.get("retrato") ? "&retrato=0" : "";
URL += this.get("título") ? "&título=0" : "";
URL += this.get("byline") ? "" : "&byline=0";
URL += this.get("color") ? "&color=" + this.get("color") : "";
URL de retorno;
},
MÉTODO PERSONALIZADO PARA CONSTRUIR MYVRSPOT IFRAME SRC
"getMyVRSpotSrc": función() {
var videoId = this.get("videoId");
var url = this.get("myvrspotUrl");
url += "?v=" + videoId;
URL de retorno;
},
MÉTODO PERSONALIZADO PARA CONSTRUIR IFRAME SRC PERSONALIZADO
"getIframeSrc": function() {
var videoId = this.get("videoId");
return videoId;
}
}
});
}
DEVUELVO UN ARRAY DE COMPONENTES/PLUGINS DEFINIDOS
return [customVideo];
},
// ...
"ExtendGrapesBlocks": función() {
var _this = esto;
BLOQUE DE VÍDEO
esto. GrapesBlocks.add("csVideo", {
etiqueta: 'Vídeo',
Contenido: {
tipo: "csVideo",
nombre: "Vídeo",
atributos: {
"data-element-type": "csVideo"
}
},
categoría: 'Multimedia',
atributos: {
"Clase": "FA FA-YouTube-Play"
},
select: true
});
},
// ...
};
})();
Preguntas y respuestas relacionadas
Continúa investigando con debates sobre temas similares.
Issue #1959
[Pregunta] Editar innerHTML en un botón personalizado
Hola a todos, Estoy intentando cambiar el texto en un componente de botón, pero no consigo editarlo. He añadido este tipo: Incluí el paráme...
Issue #2741
¿Cómo envolver un componente con nodos de texto basados en un rasgo?
Hola @artf, No estoy seguro de si esto aplica aquí, pero no consigo averiguar en la documentación cómo actualizar el modelo de componentes...
Issue #2193
[PREGUNTA] Restablecer rasgo al editar el contenido de un componente personalizado
Hola, Tengo un componente personalizado cuyo contenido se puede cambiar cambiando las opciones de selección de rasgos, pero también puede e...
Issue #3409
[PREGUNTA] Propiedad de componente personalizada que no es un rasgo
Me gustaría crear un componente personalizado con una propiedad que se actualice según un código específico, pero no quiero que esta propie...
Plugins de pago que cumplen con este problema
Seleccionado por temas clave y relevancia de etiquetas para ayudarte a enviar más rápido.
Cargando recomendaciones de plugins de pago...
Consulta los plugins de código abierto de GrapesJS en GitHub O haz una búsqueda rápida en nuestro catálogo gratuito.
Explora plugins gratuitos →Los plugins premium incluyen soporte, actualizaciones regulares y funciones listas para producción — ahorrando días de trabajo de integración.
Explora plugins premium →Explorar categorías de plugins
Ve directamente a las páginas de categorías de plugins en el marketplace.