censor(obiekt, extra)
Opis
Zwraca płytką kopię obiektu, z której usunięto atrybuty cyklu życia oraz dodatkowe atrybuty przekazane jako argument.
var attrs = { one: 'two', enabled: false, oninit: function () {} };
var censored = m.censor(attrs, ['enabled']);
// {one: "two"}
Sygnatura
censored = m.censor(object, extra)
Argument | Typ | Wymagany | Opis |
---|---|---|---|
object | Object | Tak | Obiekt typu klucz-wartość. |
extra | Array<String> | Nie | Dodatkowe nazwy właściwości do usunięcia. |
zwraca | Object | Oryginalny obiekt, jeśli nie ma właściwości do usunięcia. W przeciwnym razie zwraca płytką kopię obiektu z usuniętymi właściwościami. |
Jak to działa
Zazwyczaj nie potrzebujesz tej metody i wystarczy, że określisz tylko te atrybuty, które chcesz przekazać. Czasami jednak wygodniej jest przekazać wszystkie atrybuty (również te nieznane) do innego komponentu. Często jest to uzasadnione, ale może prowadzić do problemów, np. do dwukrotnego wywoływania metod cyklu życia.
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, [
// !!!
// ...
]);
},
};
}
Wygląda to niewinnie, ale stwarza problem: wysyłasz dwa trafienia za każdym razem, gdy następuje nawigacja do tego widoku. W tym momencie z pomocą przychodzi m.censor
: pozwala on usunąć atrybut oncreate
, dzięki czemu zostanie on wywołany tylko raz, a kod wywołujący zachowa czytelność i uniknie trudnych do zdiagnozowania błędów.
// Naprawione
function SomeFancyView() {
return {
view: function (vnode) {
return m('div', m.censor(vnode.attrs), [
// ...
]);
},
};
}
Podobne problemy mogą wystąpić również w przypadku kluczy:
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,
]),
];
},
};
}
To spowodowałoby błąd wyrzuceniem błędu, ponieważ tak wygląda vnode Layout
z perspektywy Mithril.js:
return [
m('header', [m('h1', 'My beautiful web app'), m('nav')]),
m('.body', { pageTitle: 'Some Page', key: someKey }, [
m('h2', 'Some Page'),
[
/* ... */
],
]),
];
Może to być trudne do zauważenia na pierwszy rzut oka, szczególnie w bardziej złożonych scenariuszach. Aby to naprawić, należy ocenzurować atrybut key
. Można również ocenzurować atrybut pageTitle
, ponieważ jego obecność w DOM nie wnosi żadnej wartości.
// Naprawione
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,
]),
];
},
};
}