Issue #2279✓ ResueltoAbierto el 19 de septiembre de 2019por brentonkelly1982Reacciones 6

Cómo actualizar el modelo de un componente personalizado cuando se cambia un rasgo.

Respuesta rápidapor brentonkelly19826

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)

👍 Muy útilbrentonkelly198220 de septiembre de 2019

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.

Plugins de pago que cumplen con este problema

Seleccionado por temas clave y relevancia de etiquetas para ayudarte a enviar más rápido.

Ver todos los plugins

Cargando recomendaciones de plugins de pago...

Opción gratuita

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 →
Opción premium

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.