Skip to content
Mithril.js 2
Main Navigation AnleitungAPI

Deutsch

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

Deutsch

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

Aussehen

Sidebar Navigation

Erste Schritte

Installation

Einfache Anwendung

Ressourcen

JSX

ES6+ in älteren Browsern

Animationen

Testen

Beispiele

Integration von Drittanbietern

Pfadverarbeitung

Schlüsselkonzepte

Virtuelle DOM Knoten

Komponenten

Lebenszyklus-Methoden

Keys

Das Auto-Redraw-System

Sonstiges

Framework-Vergleich

Migration von v1.x

Migration von v0.2.x auf v2.x

API

Auf dieser Seite

Migration von v0.2.x auf v2.x ​

v1.x und v2.x sind weitgehend API-kompatibel mit v0.2.x, es gibt jedoch einige Breaking Changes. Die Migration zu v2.x ist nahezu identisch mit der zu v1.x, daher gelten die folgenden Hinweise hauptsächlich für beide Versionen.

Für die Migration empfiehlt sich das Tool mithril-codemods, um einfache Migrationen zu automatisieren.

m.prop entfernt ​

In v2.x ist m.prop() nicht mehr Teil des Kerns, sondern wurde in eine leistungsfähigere Stream-Micro-Library ausgelagert. Informationen zur Verwendung des optionalen Streams-Moduls finden Sie in der Dokumentation.

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;
});

m.component entfernt ​

In v0.2.x konnten Komponenten entweder mit m(Component) oder m.component(Component) erstellt werden. v2.x unterstützt nur noch m(Component).

v0.2.x ​

javascript
// Diese sind äquivalent
m.component(Component);
m(Component);

v2.x ​

javascript
m(Component);

m.withAttr entfernt ​

In v0.2.x konnten Event-Listener oninput: m.withAttr("value", func) und ähnliches verwenden. In v2.x lesen Sie diese direkt aus dem target des Events. m.withAttr harmonierte gut mit m.prop. Da m.prop jedoch zugunsten einer externen Lösung entfernt wurde und v1.x keine ähnlich breite, idiomatische Verwendung von Streams aufwies, verlor m.withAttr den größten Teil seines Nutzens.

v0.2.x ​

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

// In Ihrer View
m('input[type=text]', {
  value: value(),
  oninput: m.withAttr('value', value),
});

v2.x ​

javascript
var value = '';

// In Ihrer View
m('input[type=text]', {
  value: value,
  oninput: function (ev) {
    value = ev.target.value;
  },
});

m.version entfernt ​

Die Angabe der Version war im Allgemeinen von geringem Nutzen. Sie können sie jederzeit selbst wieder hinzufügen. Es wird empfohlen, Feature-Erkennung zu verwenden, um zu ermitteln, welche Funktionen verfügbar sind. Die v2.x-API ist so konzipiert, dass sie dies besser ermöglicht.

config Funktion ​

In v0.2.x stellte Mithril.js eine einzelne Lifecycle-Methode bereit: config. v2.x bietet eine viel feinere Kontrolle über den Lebenszyklus eines VNodes.

v0.2.x ​

javascript
m('div', {
  config: function (element, isInitialized) {
    // wird bei jedem Neuzeichnen ausgeführt
    // isInitialized ist ein boolescher Wert, der angibt, ob der Knoten dem DOM hinzugefügt wurde
  },
});

v2.x ​

Weitere Informationen zu diesen neuen Methoden finden Sie in lifecycle-methods.md.

javascript
m('div', {
  // Wird aufgerufen, bevor der DOM-Knoten erstellt wird
  oninit: function (vnode) {
    /*...*/
  },
  // Wird aufgerufen, nachdem der DOM-Knoten erstellt wurde
  oncreate: function (vnode) {
    /*...*/
  },
  // Wird aufgerufen, bevor der Knoten aktualisiert wird. Gibt false zurück, um den Vorgang abzubrechen.
  onbeforeupdate: function (vnode, old) {
    /*...*/
  },
  // Wird aufgerufen, nachdem der Knoten aktualisiert wurde
  onupdate: function (vnode) {
    /*...*/
  },
  // Wird aufgerufen, bevor der Knoten entfernt wird. Gibt ein Promise zurück, das aufgelöst wird, wenn
  // der Knoten aus dem DOM entfernt werden kann
  onbeforeremove: function (vnode) {
    /*...*/
  },
  // Wird aufgerufen, bevor der Knoten entfernt wird, aber nachdem onbeforeremove done() aufgerufen hat
  onremove: function (vnode) {
    /*...*/
  },
});

Falls verfügbar, kann auf das DOM-Element des VNodes über vnode.dom zugegriffen werden.

Änderungen im Redraw-Verhalten ​

Die Rendering-Engine von Mithril.js arbeitet weiterhin auf der Basis von halbautomatischen globalen Redraws, aber einige APIs und Verhaltensweisen unterscheiden sich:

Keine Redraw-Sperren mehr ​

In v0.2.x erlaubte Mithril.js "Redraw-Sperren", die die Draw-Logik vorübergehend blockierten: Standardmäßig sperrte m.request die Draw-Schleife bei der Ausführung und entsperrte sie, wenn alle ausstehenden Requests aufgelöst waren. Das gleiche Verhalten konnte manuell mit m.startComputation() und m.endComputation() aufgerufen werden. Die letzteren APIs und das zugehörige Verhalten wurden in v2.x ohne Ersatz entfernt. Redraw-Sperren können zu fehlerhaften UIs führen: Die Belange eines Teils der Anwendung sollten nicht die Aktualisierung anderer Teile der Ansicht verhindern.

Abbrechen des Redraws von Event-Handlern ​

m.mount() und m.route() führen nach der Ausführung eines DOM-Event-Handlers weiterhin automatisch ein Redraw durch. Das Abbrechen dieser Redraws innerhalb Ihrer Event-Handler erfolgt jetzt, indem Sie die Eigenschaft redraw des übergebenen Event-Objekts auf false setzen.

v0.2.x ​

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

v2.x ​

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

Synchrones Redraw geändert ​

In v0.2.x war es möglich, Mithril.js zu zwingen, sofort neu zu zeichnen, indem ein Truthy-Wert an m.redraw() übergeben wurde. In v2.x wurde diese Funktionalität zur Verdeutlichung in zwei verschiedene Methoden aufgeteilt.

v0.2.x ​

javascript
m.redraw(true); // zeichnet sofort und synchron neu

v2.x ​

javascript
m.redraw(); // plant ein Redraw beim nächsten requestAnimationFrame-Tick
m.redraw.sync(); // ruft sofort ein Redraw auf und wartet, bis es abgeschlossen ist

m.startComputation/m.endComputation entfernt ​

Diese Methoden gelten als Antipattern und weisen eine Reihe problematischer Randfälle auf, daher wurden sie in v2.x ohne Ersatz entfernt.

Component controller Funktion ​

In v2.x gibt es keine controller Eigenschaft mehr in Components. Verwenden Sie stattdessen 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);
  },
});

// ODER

m.mount(document.body, {
  // `this` ist standardmäßig an `vnode.state` gebunden
  oninit: function (vnode) {
    this.fooga = 1;
  },

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

Component Argumente ​

In v2.x müssen die Argumente für eine Komponente ein Objekt sein. Einfache Werte wie String, Number oder Boolean werden als Text-Kindelemente behandelt. Auf Argumente wird innerhalb der Komponente zugegriffen, indem sie aus dem vnode.attrs Objekt gelesen werden.

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 }));

Component VNode Children ​

In v0.2.x wurden Component VNode Children nicht normalisiert, sondern einfach als zusätzliche Argumente übergeben, und sie wurden auch nicht vereinfacht (flattened). (Intern wurde nur eine teilweise angewendete Component zurückgegeben, die basierend auf der teilweise angewendeten Component unterschieden wurde.) In v2.x werden Component VNode Children über vnode.children als aufgelöstes Array von Children übergeben, aber wie in v0.2.x werden die einzelnen Children selbst nicht normalisiert, noch wird das Children-Array vereinfacht.

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';
  })
);

DOM VNode Children ​

In v0.2.x wurden die Children von DOM-Knoten wörtlich dargestellt, ohne Normalisierung, abgesehen von der direkten Verwendung der Children, wenn nur ein einzelnes Array-Child vorhanden ist. Es wurde eine Struktur zurückgegeben, die eher so aussah, wobei die Strings wörtlich dargestellt wurden.

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

// Wird zu:
{
	tag: "div",
	attrs: {},
	children: [
		"value",
		["nested"],
	]
}

In v2.x werden die Children von DOM-VNodes zu Objekten einer einzigen konsistenten Struktur normalisiert.

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

// Wird ungefähr zu:
{
	tag: "div",
	attrs: null,
	children: [
		{tag: "#", children: "value"},
		{tag: "[", children: [
			{tag: "#", children: "nested"},
		]},
	]
}

Wenn nur ein einzelnes Text-Child in einem DOM-VNode vorhanden ist, wird stattdessen text auf diesen Wert gesetzt.

javascript
m("div", "value")

// Wird ungefähr zu:
{
	tag: "div",
	attrs: null,
	text: "",
	children: undefined,
}

Weitere Informationen zur v2.x VNode-Struktur und zur Normalisierung finden Sie in den VNode-Dokumenten.

Die meisten VNode-Eigenschaften von v2.x werden hier der Kürze halber weggelassen.

Keys ​

In v0.2.x konnten Sie VNodes mit und ohne Schlüssel frei mischen.

In v2.x müssen Children-Listen von Fragmenten und Elementen entweder alle Schlüssel haben oder alle schlüssellos sein. Löcher werden für diese Prüfung ebenfalls als schlüssellos betrachtet und nicht mehr ignoriert.

Wenn Sie dies umgehen müssen, verwenden Sie das Idiom eines Fragments, das einen einzelnen VNode enthält, wie z. B. [m("div", {key: whatever})].

view() Parameter ​

In v0.2.x erhalten View-Funktionen eine Referenz auf die Controller-Instanz und (optional) alle an die Komponente übergebenen Optionen. In v2.x wird nur der vnode übergeben, genau wie die controller Funktion.

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) {
    // Verwenden Sie vnode.state anstelle von ctrl
    // Verwenden Sie vnode.attrs anstelle von options
  },
});

Übergeben von Components an m() ​

In v0.2.x konnten Sie Components als zweites Argument von m() ohne erforderliche Umschließung übergeben. Um die Konsistenz in v2.x sicherzustellen, müssen diese immer mit einem m()-Aufruf umschlossen werden.

v0.2.x ​

javascript
m('div', Component);

v2.x ​

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

Übergeben von VNodes an m.mount() und m.route() ​

In v0.2.x tolerierte m.mount(element, component) VNodes als zweite Argumente anstelle von Komponenten (auch wenn dies nicht dokumentiert war). Ebenso akzeptierte m.route(element, defaultRoute, routes) VNodes als Werte im routes Objekt.

In v2.x sind stattdessen in beiden Fällen Components erforderlich.

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 ​

In v0.2.x konnte der Routing-Modus durch Zuweisen eines Strings von "pathname", "hash" oder "search" zu m.route.mode festgelegt werden. In v1.x wurde dies durch m.route.prefix = prefix ersetzt, wobei prefix ein beliebiges Präfix sein kann. Wenn es mit # beginnt, funktioniert es im "Hash"-Modus, mit ? für den "Search"-Modus und jedes andere Zeichen (oder die leere Zeichenkette) für den "Pathname"-Modus. Es unterstützt auch Kombinationen der oben genannten, wie m.route.prefix = "/path/#!" oder ?#.

Der Standardwert wurde geändert, um ein #! (Hash-Rufzeichen)-Präfix anstelle von nur # zu verwenden. Wenn Sie also das Standardverhalten verwendet haben und Ihre bestehenden URLs beibehalten möchten, setzen Sie m.route.prefix = "#" bevor Sie die Routen initialisieren.

v0.2.x ​

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

v2.x ​

javascript
// Direkte Entsprechungen:
m.route.prefix = '#';
m.route.prefix = '';
m.route.prefix = '?';

m.route() und Anker-Tags ​

Die Handhabung von routingfähigen Links verwendet jetzt eine spezielle, eingebaute Komponente anstelle eines Attributs. Wenn Sie dies auf <button>s und dergleichen verwendet haben, können Sie diesen Tag-Namen mit einem selector: "button"-Attribut angeben.

v0.2.x ​

javascript
// When clicked this link will load the "/path" route instead of navigating
m('a', {
  href: '/path',
  config: m.route,
});

v2.x ​

javascript
// When clicked this link will load the "/path" route instead of navigating
m(m.route.Link, {
  href: '/path',
});

Pfadvorlagen ​

In v1.x gab es drei separate Pfadvorlagen-Syntaxen, die, obwohl sie ähnlich waren, zwei separat entworfene Syntaxen und drei verschiedene Implementierungen hatten. Dies wurde auf ziemlich ad-hoc-Weise definiert, und Parameter wurden im Allgemeinen nicht maskiert. Jetzt wird alles entweder kodiert, wenn es :key ist, oder roh, wenn es :key... ist. Wenn Dinge unerwartet kodiert werden, verwenden Sie :path.... Das ist im Wesentlichen alles.

Konkret wirkt sich dies wie folgt auf jede Methode aus:

m.request URLs ​

Pfadkomponenten in v2.x werden automatisch maskiert, wenn sie interpoliert werden, und sie lesen ihre Werte aus params. In v0.2.x würde m.request({url: "/user/:name/photos/:id", data: {name: "a/b", id: "c/d"}}) seine Anfrage mit der URL /user/a%2Fb/photos/c/d senden. In v2.x würde die entsprechende m.request({url: "/user/:name/photos/:id", params: {name: "a/b", id: "c/d"}}) ihre Anfrage an /user/a%2Fb/photos/c%2Fd senden. Wenn Sie absichtlich einen Schlüssel unmaskiert interpolieren wollen, verwenden Sie stattdessen :key....

Interpolationen in Inline-Abfragezeichenketten, wie in /api/search?q=:query, werden in v2.x nicht durchgeführt. Übergeben Sie diese stattdessen über params mit entsprechenden Schlüssel-Namen, ohne sie in der Abfragezeichenkette anzugeben.

Beachten Sie, dass dies auch für m.jsonp gilt. Wenn Sie von m.request + dataType: "jsonp" zu m.jsonp migrieren, müssen Sie sich dessen ebenfalls bewusst sein.

m.route(route, params, shouldReplaceHistoryEntry) Pfade ​

Diese erlauben jetzt Interpolationen und funktionieren identisch mit denen von m.request.

m.route Routenmuster ​

Pfad-Schlüssel der Form :key... geben ihre URL in v1.x dekodiert zurück, aber in v2.x die rohe URL.

Zuvor wurden Dinge wie :key.md fälschlicherweise akzeptiert, wobei der Wert des resultierenden Parameters auf keymd: "..." gesetzt wurde. Dies ist nicht mehr der Fall - die .md ist jetzt Teil des Musters, nicht des Namens.

Lesen/Schreiben der aktuellen Route ​

In v0.2.x erfolgte die gesamte Interaktion mit der aktuellen Route über m.route(). In v2.x wurde dies in zwei Funktionen aufgeteilt.

v0.2.x ​

javascript
// Getting the current route
m.route();

// Setting a new route
m.route('/other/route');

v2.x ​

javascript
// Getting the current route
m.route.get();

// Setting a new route
m.route.set('/other/route');

Zugriff auf Routenparameter ​

In v0.2.x wurde das Lesen von Routenparametern vollständig über m.route.param() abgewickelt. Diese API ist in v2.x weiterhin verfügbar, und zusätzlich werden alle Routenparameter als Eigenschaften im attrs-Objekt auf dem vnode übergeben.

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"
    },
  },
});

Erstellen/Parsen von Abfragezeichenketten ​

v0.2.x verwendete Methoden, die von m.route abhingen: m.route.buildQueryString() und m.route.parseQueryString(). In v2.x wurden diese aufgeteilt und in den Root m verschoben.

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');

Auch in v2.x wird {key: undefined} von m.buildQueryString und Methoden, die es verwenden, wie m.request, als key=undefined serialisiert. In v0.2.x wurde der Schlüssel weggelassen, und dies wurde auf m.request übertragen. Wenn Sie sich zuvor darauf verlassen haben, ändern Sie Ihren Code, um die Schlüssel vollständig aus dem Objekt zu entfernen. Es kann sich lohnen, ein einfaches Hilfsprogramm zu verwenden, um alle Schlüssel aus einem Objekt zu entfernen, dessen Werte undefined sind, wenn Sie dies nicht einfach tun können und das Verhalten von v0.2.x beibehalten müssen.

javascript
// Rufen Sie diese Funktion auf, um `undefined`-Parameter aus einem Objekt zu entfernen.
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;
}

Verhindern des Aushängens ​

Es ist nicht mehr möglich, das Aushängen über onunload's e.preventDefault() zu verhindern. Stattdessen sollten Sie explizit m.route.set aufrufen, wenn die erwarteten Bedingungen erfüllt sind.

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('/');
      },
    });
  },
};

Ausführen von Code beim Entfernen der Komponente ​

Komponenten rufen this.onunload nicht mehr auf, wenn sie entfernt werden. Sie verwenden jetzt den standardisierten Lebenszyklus-Hook 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 ​

Von m.request zurückgegebene Promises sind keine m.prop Getter-Setter mehr. Darüber hinaus werden initialValue, unwrapSuccess und unwrapError nicht mehr als Optionen unterstützt.

Darüber hinaus haben Anfragen keine m.startComputation/m.endComputation-Semantik mehr. Stattdessen werden Neuzeichnungen immer ausgelöst, wenn eine Request-Promise-Kette abgeschlossen ist (es sei denn, background: true ist gesetzt).

Der data-Parameter wurde jetzt in params (Abfrageparameter, die in die URL interpoliert und an die Anfrage angehängt werden) und body (den im zugrunde liegenden XMLHttpRequest zu sendenden Anfrageinhalt) aufgeteilt.

In v0.2.x würden Sie ein dataType: "jsonp" verwenden, um eine JSONP-Anfrage zu initiieren. In v2.x verwenden Sie jetzt m.jsonp, das größtenteils die gleiche API wie m.request ohne die XMLHttpRequest-bezogenen Teile enthält.

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); // note: Dies ist kein Getter-Setter.
}, 1000);

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

// OR

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

setTimeout(function () {
  console.log(data); // note: Dies ist kein Getter-Setter.
}, 1000);

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

Wenn die Option extract an m.request übergeben wird, wird der Rückgabewert der bereitgestellten Funktion direkt verwendet, um das Request-Promise aufzulösen, und die Rückruffunktion deserialize wird ignoriert.

m.request Header ​

In v0.2.x hat Mithril.js standardmäßig keine Header für Anfragen gesetzt. Jetzt werden bis zu zwei Header gesetzt:

  • Content-Type: application/json; charset=utf-8 für Anfragen mit JSON-Anfrageinhalten, die != null sind
  • Accept: application/json, text/* für Anfragen, die JSON-Antworten erwarten

Der Header Content-Type kann einen CORS-Prefetch auslösen, da er aufgrund des angegebenen Content-Typs nicht als CORS-safelisted Request-Header gilt. Dies kann zu neuen Fehlern führen, abhängig von der CORS-Konfiguration Ihres Servers. Wenn Sie auf Probleme damit stoßen, müssen Sie diesen Header möglicherweise überschreiben, indem Sie headers: {"Content-Type": "text/plain"} übergeben. (Der Accept-Header löst nichts aus, sodass Sie ihn nicht überschreiben müssen.)

Die einzigen Content-Typen, die die Fetch-Spezifikation zulässt, um CORS-Prefetch-Prüfungen zu vermeiden, sind application/x-www-form-urlencoded, multipart/form-data und text/plain. Es erlaubt nichts anderes und verbietet absichtlich JSON.

m.deferred entfernt ​

v0.2.x verwendete ein eigenes benutzerdefiniertes asynchrones Vertragsobjekt, das als m.deferred verfügbar gemacht wurde und als Grundlage für m.request diente. v2.x verwendet stattdessen Promises und implementiert ein Polyfill in nicht unterstützenden Umgebungen. In Situationen, in denen Sie m.deferred verwendet hätten, sollten Sie stattdessen Promises verwenden.

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);
  }); //logs "hello world" after 1 second

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);
  }); //logs "hello world" after 1 second

m.sync entfernt ​

Da v2.x standardkonforme Promises verwendet, ist m.sync redundant. Verwenden Sie stattdessen 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);
});

xlink Namespace erforderlich ​

In v0.2.x war der xlink-Namespace der einzige unterstützte Attribut-Namespace, und er wurde durch spezielles Verhalten unterstützt. Jetzt wird das Parsen von Namespaces vollständig unterstützt, und Attribute mit Namespaces sollten ihren Namespace explizit deklarieren.

v0.2.x ​

javascript
m(
  'svg',
  // the `href` attribute is namespaced automatically
  m("image[href='image.gif']")
);

v2.x ​

javascript
m(
  'svg',
  // User-specified namespace on the `href` attribute
  m("image[xlink:href='image.gif']")
);

Verschachtelte Arrays in Views ​

Arrays stellen jetzt Fragmente dar, die im virtuellen DOM von v2.x strukturell bedeutsam sind. Während verschachtelte Arrays in v0.2.x zu einer fortlaufenden Liste virtueller Knoten zum Zwecke der Unterschiedsberechnung abgeflacht würden, behält v2.x die Array-Struktur bei - die Kinder eines bestimmten Arrays werden nicht als Geschwister derer benachbarter Arrays betrachtet.

vnode Gleichheitsprüfungen ​

Wenn ein vnode identisch mit dem vnode ist, der an seiner Stelle im letzten Durchlauf war, überspringt v2.x diesen Teil des Baums, ohne Mutationen zu prüfen oder Lebenszyklus-Methoden im Unterbaum auszulösen. Die Komponentendokumentation enthält weitere Details zu diesem Problem.

Pager
Vorherige SeiteMigration von v1.x
Nächste SeiteAPI

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2024 Mithril Contributors

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

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2024 Mithril Contributors