Skip to content
Mithril.js 2
Main Navigation PrzewodnikAPI

Polski

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Türkçe
čeština
magyar

Polski

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Türkçe
čeština
magyar

Wygląd

Sidebar Navigation

Pierwsze kroki

Instalacja

Prosta aplikacja

Zasoby

JSX

ES6+ na starszych przeglądarkach

Animacje

Testowanie

Przykłady

Integracja z zewnętrznymi bibliotekami

Obsługa ścieżek

Kluczowe koncepcje

Węzły Virtual DOM

Komponenty

Metody cyklu życia

Klucze

System automatycznego odświeżania

Różne

Porównanie frameworków

Migracja z v1.x

Migracja z wersji 0.2.x

API

Na tej stronie

Migracja z wersji 0.2.x ​

Wersje v1.x i v2.x są w dużej mierze kompatybilne z API v0.2.x, jednak wprowadzono pewne zmiany powodujące brak kompatybilności wstecznej. Migracja do v2.x jest niemal identyczna z migracją do v1.x, dlatego poniższe uwagi odnoszą się do obu wersji.

Jeśli planujesz migrację, rozważ użycie narzędzia mithril-codemods, które może zautomatyzować najprostsze zadania związane z migracją.

Usunięto m.prop ​

W v2.x funkcja m.prop() została zastąpiona bardziej zaawansowaną mikro-biblioteką strumieni (stream), która jednak nie jest już częścią rdzenia biblioteki. Informacje na temat korzystania z opcjonalnego modułu Streams można znaleźć w dokumentacji.

v0.2.x ​

javascript
var m = require('mithril');

var num = m.prop(1);

v2.x ​

javascript
var m = require('mithril');
var prop = require('mithril/stream');

var num = prop(1);
var doubled = num.map(function (n) {
  return n * 2;
});

Usunięto m.component ​

W v0.2.x komponenty mogły być tworzone za pomocą m(Component) lub m.component(Component). W v2.x obsługiwane jest tylko m(Component).

v0.2.x ​

javascript
// Te zapisy są równoważne
m.component(Component);
m(Component);

v2.x ​

javascript
m(Component);

Usunięto m.withAttr ​

W v0.2.x obsługi zdarzeń mogły używać oninput: m.withAttr("value", func) i podobnych konstrukcji. W v2.x należy odczytywać wartości bezpośrednio z elementu docelowego zdarzenia. Funkcja m.withAttr dobrze współgrała z m.prop, ale została usunięta na rzecz rozwiązania spoza rdzenia. Ponieważ w v1.x nie zaobserwowano podobnego, szerokiego i idiomatycznego użycia strumieni, m.withAttr straciło większość swojej użyteczności.

v0.2.x ​

javascript
var value = m.prop('');

// W twoim widoku
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', value),
});

v2.x ​

javascript
var value = '';

// W twoim widoku
m('input[type=text]', {
  value: value,
  oninput: function (ev) {
    value = ev.target.value;
  },
});

Usunięto m.version ​

Ogólnie rzecz biorąc, funkcja ta miała niewielkie zastosowanie. Zawsze możesz ją dodać samodzielnie. Zaleca się wykrywanie funkcjonalności, aby określić, jakie funkcje są dostępne. API v2.x zostało zaprojektowane tak, aby to ułatwić.

Funkcje cyklu życia komponentu (dawniej config) ​

W v0.2.x Mithril.js udostępniał pojedynczą metodę cyklu życia, config. W v2.x zapewnia znacznie bardziej szczegółową kontrolę nad cyklem życia vnode (węzła wirtualnego DOM).

v0.2.x ​

javascript
m('div', {
  config: function (element, isInitialized) {
    // uruchamia się przy każdym odświeżeniu
    // isInitialized to wartość boolean, która reprezentuje, czy węzeł został dodany do DOM
  },
});

v2.x ​

Szczegółowe informacje na temat nowych metod cyklu życia można znaleźć w lifecycle-methods.md.

javascript
m('div', {
  // Wywoływane przed utworzeniem węzła DOM
  oninit: function (vnode) {
    /*...*/
  },
  // Wywoływane po utworzeniu węzła DOM
  oncreate: function (vnode) {
    /*...*/
  },
  // Wywoływane przed aktualizacją węzła, zwraca false, aby anulować aktualizację
  onbeforeupdate: function (vnode, old) {
    /*...*/
  },
  // Wywoływane po aktualizacji węzła
  onupdate: function (vnode) {
    /*...*/
  },
  // Wywoływane przed usunięciem węzła, zwraca Promise, który jest resolved, gdy
  // węzeł jest gotowy do usunięcia z DOM
  onbeforeremove: function (vnode) {
    /*...*/
  },
  // Wywoływane po wywołaniu onbeforeremove i jego zakończeniu (Promise resolved), tuż przed usunięciem węzła
  onremove: function (vnode) {
    /*...*/
  },
});

Jeśli jest dostępny, element DOM vnode można uzyskać poprzez właściwość vnode.dom.

Zmiany w zachowaniu odświeżania (redraw behaviour) ​

Silnik renderowania Mithril.js nadal działa w oparciu o półautomatyczne globalne odświeżania, ale niektóre API i zachowania uległy zmianie:

Brak blokad odświeżania (redraw locks) ​

W v0.2.x Mithril.js pozwalał na "blokady odświeżania", które tymczasowo uniemożliwiały wykonywanie logiki rysowania: domyślnie, m.request blokował pętlę renderowania podczas wykonywania i odblokowywał ją po zakończeniu wszystkich oczekujących żądań. To samo zachowanie można było wywołać ręcznie za pomocą m.startComputation() i m.endComputation(). Te API i powiązane zachowanie zostały usunięte w v2.x bez zamiennika. Blokowanie odświeżania może prowadzić do nieprawidłowego działania interfejsu użytkownika: problemy w jednej części aplikacji nie powinny uniemożliwiać aktualizacji innych części widoku i odzwierciedlania zmian.

Anulowanie odświeżania (redraw) z obsługi zdarzeń (event handlers) ​

m.mount() i m.route() nadal automatycznie odświeżają widok po uruchomieniu obsługi zdarzeń DOM. Anulowanie tych odświeżeń w obsłudze zdarzeń odbywa się teraz poprzez ustawienie właściwości redraw na false w obiekcie zdarzenia.

v0.2.x ​

javascript
m('div', {
  onclick: function (e) {
    m.redraw.strategy('none');
  },
});

v2.x ​

javascript
m('div', {
  onclick: function (e) {
    e.redraw = false;
  },
});

Zmieniono synchroniczne odświeżanie (synchronous redraw) ​

W v0.2.x można było wymusić na Mithril.js natychmiastowe odświeżenie poprzez przekazanie wartości true do m.redraw(). W v2.x ta funkcjonalność została podzielona na dwie różne metody dla większej przejrzystości.

v0.2.x ​

javascript
m.redraw(true); // odświeża natychmiast i synchronicznie

v2.x ​

javascript
m.redraw(); // planuje odświeżenie na następny tick requestAnimationFrame
m.redraw.sync(); // wywołuje odświeżenie natychmiast i czeka na jego zakończenie

Usunięto m.startComputation/m.endComputation ​

Uznano je za złą praktykę i miały szereg problematycznych przypadków brzegowych, dlatego zostały usunięte w v2.x bez zamiennika.

Funkcja controller komponentu ​

W v2.x właściwość controller w komponentach została usunięta - zamiast niej należy używać oninit.

v0.2.x ​

javascript
m.mount(document.body, {
  controller: function () {
    var ctrl = this;

    ctrl.fooga = 1;
  },

  view: function (ctrl) {
    return m('p', ctrl.fooga);
  },
});

v2.x ​

javascript
m.mount(document.body, {
  oninit: function (vnode) {
    vnode.state.fooga = 1;
  },

  view: function (vnode) {
    return m('p', vnode.state.fooga);
  },
});

// LUB

m.mount(document.body, {
  // `this` domyślnie wskazuje na vnode.state
  oninit: function (vnode) {
    this.fooga = 1;
  },

  view: function (vnode) {
    return m('p', this.fooga);
  },
});

Argumenty komponentu ​

W v2.x argumenty przekazywane do komponentu muszą być obiektem. Proste wartości, takie jak String/Number/Boolean, będą traktowane jako tekstowe elementy potomne (text children). Dostęp do argumentów w komponencie uzyskuje się poprzez odczytywanie ich z obiektu vnode.attrs.

v0.2.x ​

javascript
var Component = {
  controller: function (options) {
    // options.fooga === 1
  },

  view: function (ctrl, options) {
    // options.fooga === 1
  },
};

m('div', m.component(Component, { fooga: 1 }));

v2.x ​

javascript
var Component = {
  oninit: function (vnode) {
    // vnode.attrs.fooga === 1
  },

  view: function (vnode) {
    // vnode.attrs.fooga === 1
  },
};

m('div', m(Component, { fooga: 1 }));

Elementy potomne vnode komponentu ​

W v2.x elementy potomne vnode komponentu są przekazywane przez vnode.children jako przetworzona tablica elementów potomnych. Podobnie jak w v0.2.x, same elementy potomne nie są normalizowane, a tablica elementów potomnych nie jest spłaszczana.

v0.2.x ​

javascript
var Component = {
  controller: function (value, renderProp) {
    // value === "value"
    // typeof renderProp === "function"
  },

  view: function (ctrl, value, renderProp) {
    // value === "value"
    // typeof renderProp === "function"
  },
};

m(
  'div',
  m.component(Component, 'value', function (key) {
    return 'child';
  })
);

v2.x ​

javascript
var Component = {
  oninit: function (vnode) {
    // vnode.children[0] === "value"
    // typeof vnode.children[1] === "function"
  },

  view: function (vnode) {
    // vnode.children[0] === "value"
    // typeof vnode.children[1] === "function"
  },
};

m(
  'div',
  m(Component, 'value', function (key) {
    return 'child';
  })
);

Elementy potomne vnode DOM ​

W v0.2.x elementy potomne węzłów DOM były reprezentowane dosłownie, bez normalizacji, chyba że obecny był tylko jeden element potomny w tablicy - wtedy używano go bezpośrednio. Powodowało to powstawanie struktury bardziej zbliżonej do tej, z łańcuchami znaków reprezentowanymi dosłownie.

javascript
m("div", "value", ["nested"])

// Staje się:
{
	tag: "div",
	attrs: {},
	children: [
		"value",
		["nested"],
	]
}

W v2.x elementy potomne vnodes DOM są normalizowane do obiektów o jednolitej strukturze.

javascript
m("div", "value", ["nested"])

// Staje się z grubsza:
{
	tag: "div",
	attrs: null,
	children: [
		{tag: "#", children: "value"},
		{tag: "[", children: [
			{tag: "#", children: "nested"},
		]},
	]
}

Jeśli na vnode DOM znajduje się tylko jeden tekstowy element potomny, zamiast tego ustawia text na tę wartość.

javascript
m("div", "value")

// Staje się z grubsza:
{
	tag: "div",
	attrs: null,
	text: "",
	children: undefined,
}

Szczegółowe informacje na temat struktury vnode v2.x i sposobu normalizacji można znaleźć w dokumentacji vnode.

Większość właściwości vnode v2.x jest tutaj pominięta dla zwięzłości.

Klucze (Keys) ​

W v0.2.x można było swobodnie mieszać vnodes z kluczami oraz bez kluczy.

W v2.x listy elementów potomnych zarówno fragmentów, jak i elementów muszą być albo wszystkie z kluczami, albo wszystkie bez kluczy. Puste miejsca są również uważane za elementy bez kluczy do celów tego sprawdzenia - nie są już ignorowane.

Jeśli musisz to obejść, użyj fragmentu zawierającego pojedynczy vnode.

Parametry view() ​

W v0.2.x funkcje widoku otrzymywały odniesienie do instancji controller i (opcjonalnie) wszelkie opcje przekazane do komponentu. W v2.x otrzymują tylko vnode, dokładnie tak samo jak funkcja oninit.

v0.2.x ​

javascript
m.mount(document.body, {
  controller: function () {},

  view: function (ctrl, options) {
    // ...
  },
});

v2.x ​

javascript
m.mount(document.body, {
  oninit: function (vnode) {
    // ...
  },

  view: function (vnode) {
    // Użyj vnode.state zamiast ctrl
    // Użyj vnode.attrs zamiast options
  },
});

Przekazywanie komponentów do m() ​

W v2.x, dla zachowania spójności, komponenty muszą być zawsze opakowane wywołaniem m().

v0.2.x ​

javascript
m('div', Component);

v2.x ​

javascript
m('div', m(Component));

Przekazywanie vnodes do m.mount() i m.route() ​

W v0.2.x, m.mount(element, component) tolerował vnodes jako drugi argument zamiast komponentów (mimo że nie było to udokumentowane). Podobnie, m.route(element, defaultRoute, routes) akceptował vnodes jako wartości w obiekcie routes.

W v2.x w obu przypadkach wymagane jest użycie komponentów.

v0.2.x ​

javascript
m.mount(element, m('i', 'hello'));
m.mount(element, m(Component, attrs));

m.route(element, '/', {
  '/': m('b', 'bye'),
});

v2.x ​

javascript
m.mount(element, {
  view: function () {
    return m('i', 'hello');
  },
});
m.mount(element, {
  view: function () {
    return m(Component, attrs);
  },
});

m.route(element, '/', {
  '/': {
    view: function () {
      return m('b', 'bye');
    },
  },
});

m.route.mode ​

W wersji 0.2.x można było ustawić tryb routingu, przypisując ciąg znaków "pathname", "hash" lub "search" do m.route.mode. W wersji v.1.x zostało to zastąpione przez m.route.prefix = prefix, gdzie prefix może być dowolnym prefiksem. Jeśli zaczyna się od #, działa w trybie "hash"; jeśli od ?, w trybie "search"; w przeciwnym razie (dowolny inny znak lub pusty ciąg znaków) w trybie "pathname". Obsługiwane są również kombinacje powyższych, takie jak m.route.prefix = "/path/#!" lub ?#.

Domyślne ustawienie zostało zmienione, aby używać prefiksu #! (hashbang) zamiast tylko #. Jeśli więc używałeś domyślnego zachowania i chcesz zachować istniejące adresy URL, ustaw m.route.prefix = "#" przed zainicjowaniem tras.

v0.2.x ​

javascript
m.route.mode = 'hash';
m.route.mode = 'pathname';
m.route.mode = 'search';

v2.x ​

javascript
// Bezpośrednie odpowiedniki
m.route.prefix = '#';
m.route.prefix = '';
m.route.prefix = '?';

m.route() i kotwice ​

Do obsługi linków z routingiem używany jest teraz specjalny, wbudowany komponent, zamiast atrybutu. Jeśli używałeś tego na elementach <button> i tym podobnych, możesz określić nazwę tego tagu za pomocą atrybutu selector: "button".

v0.2.x ​

javascript
// Po kliknięciu ten link załaduje trasę "/path" zamiast nawigować
m('a', {
  href: '/path',
  config: m.route,
});

v2.x ​

javascript
// Po kliknięciu ten link załaduje trasę "/path" zamiast nawigować
m(m.route.Link, {
  href: '/path',
});

Szablony tras ​

W wersji 1.x istniały trzy oddzielne składnie szablonów ścieżek, które, choć podobne, miały 2 oddzielnie zaprojektowane składnie i 3 różne implementacje. Zostało to zdefiniowane w sposób doraźny, a parametry zazwyczaj nie były eskejpowane. Teraz, jeśli użyjesz :key, wszystko zostanie zakodowane, a jeśli :key..., pozostanie surowe. Jeśli coś jest kodowane w sposób nieoczekiwany, użyj :path.... To proste.

Konkretnie, oto jak wpływa to na każdą metodę:

Adresy URL m.request ​

W wersji 2.x, składniki ścieżki są automatycznie eskejpowane podczas interpolacji, a ich wartości odczytywane są z params. W wersji 0.2.x, m.request({url: "/user/:name/photos/:id", data: {name: "a/b", id: "c/d"}}) wysłałoby żądanie z adresem URL ustawionym na /user/a%2Fb/photos/c/d. W wersji 2.x, odpowiadające m.request({url: "/user/:name/photos/:id", params: {name: "a/b", id: "c/d"}}) wysłałoby żądanie do /user/a%2Fb/photos/c%2Fd. Jeśli celowo chcesz interpolować klucz bez eskejpownia, użyj :key....

W wersji 2.x interpolacje w wbudowanych ciągach zapytania, takich jak /api/search?q=:query, nie są wykonywane. Przekaż je przez params z odpowiednimi nazwami kluczy, bez określania ich w ciągu zapytania.

Zauważ, że dotyczy to również m.jsonp. Podczas migracji z m.request + dataType: "jsonp" do m.jsonp, musisz również o tym pamiętać.

Ścieżki m.route(route, params, shouldReplaceHistoryEntry) ​

Umożliwiają teraz interpolacje i działają identycznie jak w przypadku m.request.

Wzorce tras m.route ​

Klucze ścieżki w postaci :key... zwracały swój adres URL zdekodowany w wersji 1.x, ale zwracają surowy adres URL w wersji 2.x.

Wcześniej, elementy takie jak :key.md były błędnie akceptowane, a wartość wynikowego parametru była ustawiana na keymd: "...". Tak już nie jest - .md jest teraz częścią wzorca, a nie nazwą.

Odczyt/zapis bieżącej trasy ​

W wersji 0.2.x cała interakcja z bieżącą trasą odbywała się za pomocą m.route(). W wersji 2.x zostało to podzielone na dwie funkcje.

v0.2.x ​

javascript
// Pobieranie bieżącej trasy
m.route();

// Ustawianie nowej trasy
m.route('/other/route');

v2.x ​

javascript
// Pobieranie bieżącej trasy
m.route.get();

// Ustawianie nowej trasy
m.route.set('/other/route');

Dostęp do parametrów trasy ​

W wersji 0.2.x odczytywanie parametrów trasy było w całości obsługiwane przez m.route.param(). To API jest nadal dostępne w wersji 2.x. Dodatkowo, wszystkie parametry trasy są przekazywane jako właściwości w obiekcie attrs węzła wirtualnego (vnode).

v0.2.x ​

javascript
m.route(document.body, '/booga', {
  '/:attr': {
    controller: function () {
      m.route.param('attr'); // "booga"
    },
    view: function () {
      m.route.param('attr'); // "booga"
    },
  },
});

v2.x ​

javascript
m.route(document.body, '/booga', {
  '/:attr': {
    oninit: function (vnode) {
      vnode.attrs.attr; // "booga"
      m.route.param('attr'); // "booga"
    },
    view: function (vnode) {
      vnode.attrs.attr; // "booga"
      m.route.param('attr'); // "booga"
    },
  },
});

Budowanie/Parsowanie ciągów zapytań ​

W wersji 0.2.x używano metod m.route.buildQueryString() i m.route.parseQueryString(), które były częścią obiektu m.route. W wersji 2.x zostały one rozdzielone i przeniesione do korzenia m.

v0.2.x ​

javascript
var qs = m.route.buildQueryString({ a: 1 });

var obj = m.route.parseQueryString('a=1');

v2.x ​

javascript
var qs = m.buildQueryString({ a: 1 });

var obj = m.parseQueryString('a=1');

Ponadto, w wersji 2.x, {key: undefined} jest serializowane jako key=undefined przez m.buildQueryString i metody, które go używają, takie jak m.request. W wersji 0.2.x klucz został pominięty i przeniesiono to do m.request. Jeśli wcześniej na tym polegałeś, zmień swój kod, aby całkowicie pominąć klucze z obiektu. Jeśli nie możesz łatwo tego zrobić i musisz zachować zachowanie z wersji 0.2.x, rozważ użycie prostego narzędzia do usuwania wszystkich kluczy z obiektu, których wartości są undefined.

javascript
// Wywołaj, gdy musisz pominąć parametry `undefined` z obiektu.
function omitUndefineds(object) {
  var result = {};

  for (var key in object) {
    if ({}.hasOwnProperty.call(object, key)) {
      var value = object[key];
      if (Array.isArray(value)) {
        result[key] = value.map(omitUndefineds);
      } else if (value != null && typeof value === 'object') {
        result[key] = omitUndefineds(value);
      } else if (value !== undefined) {
        result[key] = value;
      }
    }
  }

  return result;
}

Zapobieganie usuwaniu ​

Zapobieganie odmontowywaniu za pomocą e.preventDefault() w funkcji onunload nie jest już możliwe. Zamiast tego powinieneś jawnie wywołać m.route.set, gdy zostaną spełnione oczekiwane warunki.

v0.2.x ​

javascript
var Component = {
  controller: function () {
    this.onunload = function (e) {
      if (condition) e.preventDefault();
    };
  },
  view: function () {
    return m('a[href=/]', { config: m.route });
  },
};

v2.x ​

javascript
var Component = {
  view: function () {
    return m('a', {
      onclick: function () {
        if (!condition) m.route.set('/');
      },
    });
  },
};

Wykonywanie kodu przy usuwaniu komponentu ​

Gdy komponenty są usuwane, funkcja this.onunload nie jest już wywoływana. Używają teraz standardowego haka cyklu życia onremove.

v0.2.x ​

javascript
var Component = {
  controller: function () {
    this.onunload = function (e) {
      // ...
    };
  },
  view: function () {
    // ...
  },
};

v2.x ​

javascript
var Component = {
	onremove: function() {
		// ...
	}
	view: function() {
		// ...
	}
}

m.request ​

Obietnice zwracane przez m.request nie są już getterami i setterami typu m.prop. Ponadto, initialValue, unwrapSuccess i unwrapError nie są już obsługiwanymi opcjami.

Ponadto, żądania nie korzystają już z semantyki m.startComputation/m.endComputation. Zamiast tego, przerysowania są zawsze wyzwalane po zakończeniu łańcucha obietnic żądania (chyba że ustawiono background: true).

Parametr data został podzielony na params (parametry zapytania interpolowane do adresu URL i dołączone do żądania) oraz body (treść do wysłania w bazowym XHR).

W wersji 0.2.x do zainicjowania żądania JSONP używało się dataType: "jsonp". W wersji 2.x używane jest m.jsonp, które ma API w większości identyczne z m.request, ale bez części związanych z XHR.

v0.2.x ​

javascript
var data = m.request({
  method: 'GET',
  url: 'https://api.github.com/',
  initialValue: [],
});

setTimeout(function () {
  console.log(data());
}, 1000);

m.request({
  method: 'POST',
  url: 'https://api.github.com/',
  data: someJson,
});

v2.x ​

javascript
var data = [];
m.request({
  method: 'GET',
  url: 'https://api.github.com/',
}).then(function (responseBody) {
  data = responseBody;
});

setTimeout(function () {
  console.log(data); // uwaga: nie jest to getter-setter
}, 1000);

m.request({
  method: 'POST',
  url: 'https://api.github.com/',
  body: someJson,
});

// LUB

var data = [];
m.request('https://api.github.com/').then(function (responseBody) {
  data = responseBody;
});

setTimeout(function () {
  console.log(data); // uwaga: nie jest to getter-setter
}, 1000);

m.request('https://api.github.com/', {
  method: 'POST',
  body: someJson,
});

Dodatkowo, jeśli opcja extract zostanie przekazana do m.request, wartość zwracana przez dostarczoną funkcję zostanie użyta bezpośrednio do rozwiązania obietnicy żądania, a funkcja zwrotna deserialize zostanie zignorowana.

Nagłówki m.request ​

W wersji 0.2.x Mithril.js domyślnie nie ustawiał żadnych nagłówków w żądaniach. Teraz ustawia do 2 nagłówków:

  • Content-Type: application/json; charset=utf-8 dla żądań z treścią JSON, która jest != null
  • Accept: application/json, text/* dla żądań oczekujących odpowiedzi JSON

Pierwszy z tych nagłówków, Content-Type, spowoduje wykonanie preflight CORS, ponieważ ze względu na określony typ zawartości nie znajduje się na liście bezpiecznych nagłówków CORS, co może prowadzić do nowych błędów, w zależności od konfiguracji CORS na serwerze. W przypadku problemów, możesz zastąpić ten nagłówek, przekazując headers: {"Content-Type": "text/plain"}. (Nagłówek Accept nie wyzwala preflight, więc nie musisz go zastępować.)

Specyfikacja Fetch pozwala uniknąć sprawdzania preflight CORS tylko dla typów zawartości: application/x-www-form-urlencoded, multipart/form-data i text/plain. Inne typy są niedozwolone, a JSON jest celowo zabroniony.

m.deferred usunięte ​

W wersji 0.2.x używano niestandardowego obiektu kontraktu asynchronicznego m.deferred, który stanowił podstawę dla m.request. W wersji 2.x używane są obietnice, a w środowiskach, które ich nie obsługują, implementowany jest polyfill. Zamiast m.deferred, używaj obietnic.

v0.2.x ​

javascript
var greetAsync = function () {
  var deferred = m.deferred();
  setTimeout(function () {
    deferred.resolve('hello');
  }, 1000);
  return deferred.promise;
};

greetAsync()
  .then(function (value) {
    return value + ' world';
  })
  .then(function (value) {
    console.log(value);
  }); //wyświetli "hello world" po 1 sekundzie

v2.x ​

javascript
var greetAsync = function () {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve('hello');
    }, 1000);
  });
};

greetAsync()
  .then(function (value) {
    return value + ' world';
  })
  .then(function (value) {
    console.log(value);
  }); //wyświetli "hello world" po 1 sekundzie

m.sync usunięte ​

m.sync jest zbędne, ponieważ wersja 2.x używa obietnic zgodnych ze standardami. Użyj zamiast tego Promise.all.

v0.2.x ​

javascript
m.sync([
  m.request({ method: 'GET', url: 'https://api.github.com/users/lhorie' }),
  m.request({
    method: 'GET',
    url: 'https://api.github.com/users/dead-claudia',
  }),
]).then(function (users) {
  console.log('Contributors:', users[0].name, 'and', users[1].name);
});

v2.x ​

javascript
Promise.all([
  m.request({ method: 'GET', url: 'https://api.github.com/users/lhorie' }),
  m.request({
    method: 'GET',
    url: 'https://api.github.com/users/dead-claudia',
  }),
]).then(function (users) {
  console.log('Contributors:', users[0].name, 'and', users[1].name);
});

Wymagana przestrzeń nazw xlink ​

W wersji 0.2.x xlink była jedyną obsługiwaną przestrzenią nazw atrybutów i była obsługiwana w specjalny sposób. Obecnie parsowanie przestrzeni nazw jest w pełni obsługiwane, a atrybuty z przestrzenią nazw muszą jawnie deklarować swoją przestrzeń nazw.

v0.2.x ​

javascript
m(
  'svg',
  // przestrzeń nazw atrybutu `href` jest przypisywana automatycznie
  m("image[href='image.gif']")
);

v2.x ​

javascript
m(
  'svg',
  // Przestrzeń nazw określona przez użytkownika na atrybucie `href`
  m("image[xlink:href='image.gif']")
);

Zagnieżdżone tablice w widokach komponentów ​

Tablice reprezentują teraz fragmenty, które w wirtualnym DOM w wersji 2.x mają istotne znaczenie strukturalne. W wersji 0.2.x zagnieżdżone tablice były spłaszczane do jednej, ciągłej listy wirtualnych węzłów na potrzeby porównywania różnic. W wersji 2.x struktura tablicy jest zachowywana, a elementy potomne danej tablicy nie są traktowane jako elementy równorzędne z sąsiednich tablic.

Sprawdzanie równości vnode ​

Jeśli węzeł wirtualny (vnode) jest ściśle równy węzłowi zajmującemu jego miejsce w ostatnim renderowaniu, wersja 2.x pominie tę część drzewa, nie sprawdzając mutacji i nie wyzwalając żadnych metod cyklu życia w poddrzewie. Dokumentacja komponentu zawiera więcej szczegółów na ten temat.

Pager
Poprzednia stronaMigracja z v1.x
Następna stronaAPI

Opublikowano na licencji MIT.

Copyright (c) 2024 Mithril Contributors

https://mithril.js.org/migration-v02x.html

Opublikowano na licencji MIT.

Copyright (c) 2024 Mithril Contributors