censor(object, extra)
Описание
Возвращает поверхностную копию объекта, из которой удалены атрибуты жизненного цикла Mithril.js и любые пользовательские атрибуты, указанные в параметре extra
.
var attrs = { one: 'two', enabled: false, oninit: function () {} };
var censored = m.censor(attrs, ['enabled']);
// {one: "two"}
Сигнатура
censored = m.censor(object, extra)
Аргумент | Тип | Обязательный | Описание |
---|---|---|---|
object | Object | Да | Объект, представляющий собой набор пар ключ-значение, из которого необходимо удалить атрибуты. |
extra | Array<String> | Нет | Массив строк, содержащий имена дополнительных свойств, которые также необходимо исключить. |
возвращает | Object | Поверхностная копия исходного объекта с удаленными указанными свойствами. Если в исходном объекте не было свойств для исключения, возвращается исходный объект. |
Как это работает
Обычно нет необходимости использовать этот метод напрямую, так как достаточно явно указать только необходимые атрибуты. Однако, в некоторых случаях удобнее передать все атрибуты (включая неизвестные) другому компоненту. Хотя это может показаться разумным, это может привести к проблемам, особенно когда методы жизненного цикла вызываются несколько раз.
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, [
// !!!
// ...
]);
},
};
}
Этот код выглядит безобидно, но он создает проблему: функция sendViewHit
вызывается дважды при каждой навигации к этому представлению. Именно здесь m.censor
приходит на помощь: он позволяет удалить атрибут oncreate
из атрибутов, чтобы он вызывался только один раз, и чтобы вызывающий компонент оставался "в неведении".
// Fixed
function SomeFancyView() {
return {
view: function (vnode) {
return m('div', m.censor(vnode.attrs), [
// ...
]);
},
};
}
Аналогичные проблемы могут возникнуть с атрибутом key
:
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,
]),
];
},
};
}
Это приведет к ошибке, потому что при создании vnode Layout
Mithril.js увидит следующее:
return [
m('header', [m('h1', 'My beautiful web app'), m('nav')]),
m('.body', { pageTitle: 'Some Page', key: someKey }, [
m('h2', 'Some Page'),
[
/* ... */
],
]),
];
Эту проблему сложно заметить при первом взгляде на код, особенно в реальных сценариях со сложной структурой и/или другими проблемами. Чтобы исправить это, необходимо удалить атрибут key
. Также можно исключить пользовательский атрибут pageTitle
, так как его присутствие в DOM не имеет смысла.
// 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,
]),
];
},
};
}