censor(object, extra)
Descripción
Devuelve un objeto clonado superficialmente, excluyendo los atributos de ciclo de vida y cualquier atributo personalizado especificado.
var attrs = { one: 'two', enabled: false, oninit: function () {} };
var censored = m.censor(attrs, ['enabled']);
// {one: "two"}
Firma
censored = m.censor(object, extra)
Argumento | Tipo | Requerido | Descripción |
---|---|---|---|
objeto | Object | Sí | Un mapa clave-valor. |
extra | Array<String> | No | Propiedades adicionales que se deben omitir. |
devuelve | Object | El objeto original si no hay propiedades para omitir; de lo contrario, un objeto clonado superficialmente con las propiedades excluidas. |
Cómo funciona
Normalmente, no es necesario este método; basta con especificar los atributos deseados. Sin embargo, a veces es más conveniente pasar todos los atributos desconocidos a otro elemento. Esto puede ser razonable, pero puede llevar a un problema importante con los métodos de ciclo de vida, que podrían llamarse dos veces.
function SomePage() {
return {
view: function () {
return m(SomeFancyView, {
oncreate: function () {
sendViewHit(m.route.get(), 'some fancy view');
},
});
},
};
}
function SomeFancyView() {
return {
view: function (vnode) {
return m('div', vnode.attrs, [
// !!!
// ...
]);
},
};
}
Esto parece inofensivo, pero crea un problema: se están enviando dos hits cada vez que se navega a esta vista. Aquí es donde entra m.censor
: permite eliminar oncreate
de los atributos, asegurando que se llame solo una vez y evitando comportamientos inesperados.
// Fixed
function SomeFancyView() {
return {
view: function (vnode) {
return m('div', m.censor(vnode.attrs), [
// ...
]);
},
};
}
También se pueden encontrar problemas similares con las claves:
function SomePage() {
return {
view: function () {
return m(
Layout,
{
pageTitle: 'Some Page',
key: someKey,
},
[
// ...
]
);
},
};
}
function Layout() {
return {
view: function (vnode) {
return [
m('header', [m('h1', 'My beautiful web app'), m('nav')]),
m('.body', vnode.attrs, [
// !!!
m('h2', vnode.attrs.pageTitle),
vnode.children,
]),
];
},
};
}
Esto terminaría lanzando un error porque esto es lo que Mithril.js ve al crear el vnode Layout
:
return [
m('header', [m('h1', 'My beautiful web app'), m('nav')]),
m('.body', { pageTitle: 'Some Page', key: someKey }, [
m('h2', 'Some Page'),
[
/* ... */
],
]),
];
Es poco probable que se note esto a primera vista, especialmente en escenarios mucho más complejos donde podría haber indirección y/u otros problemas. Para corregir esto, de manera similar, se debe censurar el atributo key
. También se puede censurar el atributo personalizado pageTitle
, ya que su presencia en el DOM no aporta ningún valor.
// Fixed
function Layout() {
return {
view: function (vnode) {
return [
m('header', [m('h1', 'My beautiful web app'), m('nav')]),
m('.body', m.censor(vnode.attrs, ['pageTitle']), [
m('h2', vnode.attrs.pageTitle),
vnode.children,
]),
];
},
};
}