Általános hibák a Total.js 5-vel, téves és helyes kódmal
A hibák, amelyeket a modellek és az emberek elkövetnek Total.js 5, mindegyik a wrong kódot és a **jobb* kódot tartalmazza. /preferences.jsonl.
Egy PATCH, amely felülírja a nem elküldött mezőket
A PATCH-nek csak a kérés mezőit szabad módosítania. Alapértelmezés szerint az input-ban deklarált, de nem elküldött mező a típusa alapértelmezett értékével töltődik ki, és a frissítés ezt az üres értéket mentené el. A partial: true beállítás csak az elküldött mezőket tartja meg.
NEWACTION('Wrong/patch', {
name: 'Patch',
input: 'name:String, price:Number',
action: function($, model) {
$.callback(model);
}
});
exports.install = function() {
ROUTE('PATCH /wrong/patch/ --> *Wrong/patch');
};NEWACTION('Right/patch', {
name: 'Patch',
partial: true,
input: 'name:String, price:Number',
action: function($, model) {
$.callback(model);
}
});
exports.install = function() {
ROUTE('PATCH /right/patch/ --> *Right/patch');
};Egy jelzőkkel ellátott útvonal, amely sosem érhető el
A jelzőkkel ellátott útvonalakat az ugyanazon az URL-en lévő, jelzők nélküli útvonal után ellenőrzi a rendszer. Ha mindkettő létezik, a jelzők nélküli útvonal minden kérést átvesz. Deklarálj egy útvonalat, és a kezelőben dönts.
exports.install = function() {
ROUTE('GET /wrong/flags/', normal);
ROUTE('GET /wrong/flags/ @xhr', ajax);
};
function normal($) {
$.json({ handler: 'normal' });
}
function ajax($) {
$.json({ handler: 'ajax' });
}exports.install = function() {
ROUTE('GET /right/flags/', answer);
};
function answer($) {
$.json({ handler: $.xhr ? 'ajax' : 'normal' });
}Egy útvonal kiterjesztéssel rendelkező URL-hez
A kiterjesztéssel végződő URL, például a /report.csv, fájlkérés. Egy GET útvonal nem illeszkedik rá, és a kérés 404-gyel végződik. Deklaráld a FILE-lal.
exports.install = function() {
ROUTE('GET /wrong-report.csv', report);
};
function report($) {
$.plain('a,b\n1,2\n');
}exports.install = function() {
ROUTE('FILE /right-report.csv', report);
};
function report($) {
$.plain('a,b\n1,2\n');
}Egy CRON-sor lépésközzel
A perceket listaként írd: a 0,15,30,45 pontosan ezekre a percekre illik. Egy feladat check(date) hívása megmondja, hogy egy dátum illik-e, így az ütemezés várakozás nélkül tesztelhető.
var job = CRON('*/15 * * * *', function() {});
exports.install = function() {
ROUTE('GET /wrong/cron/', function($) {
$.json({ minute31: job.check(new Date(2026, 0, 5, 9, 31)) });
});
};var job = CRON('0,15,30,45 * * * *', function() {});
exports.install = function() {
ROUTE('GET /right/cron/', function($) {
$.json({ minute31: job.check(new Date(2026, 0, 5, 9, 31)), minute30: job.check(new Date(2026, 0, 5, 9, 30)) });
});
};Azt várni, hogy egy művelet cache beállítása gyorsítótáraz
Egy akció válaszát tárold a CACHE.set() segítségével, és olvasd a CACHE.get() hívással.
var runs = { wrong: 0 };
NEWACTION('Wrong/cached', {
name: 'Cached',
cache: { expire: '1 minute' },
action: function($) {
runs.wrong++;
$.callback({ runs: runs.wrong });
}
});
exports.install = function() {
ROUTE('GET /wrong/cache/ --> *Wrong/cached');
};var runs = { right: 0 };
NEWACTION('Right/cached', {
name: 'Cached',
action: function($) {
var cached = CACHE.get('right-cached');
if (cached)
return $.callback(cached);
runs.right++;
var value = { runs: runs.right };
CACHE.set('right-cached', value, '1 minute');
$.callback(value);
}
});
exports.install = function() {
ROUTE('GET /right/cache/ --> *Right/cached');
};Kód egy olyan mappában, amely nincs betöltve
A Total.js a projektstruktúra oldalon felsorolt mappák fájljait futtatja. A sources/ mappában lévő fájl nem fut le, ezért az induláskor futtatandó kód a definitions/ mappába való.
(MAIN.started = MAIN.started || []).push('sources');(MAIN.started = MAIN.started || []).push('definitions');
ROUTE('GET /started/', function($) {
$.json(MAIN.started);
});Szöveg hozzáfűzése a PATH.root()-hoz
A PATH.root() záró perjel nélküli útvonalat ad vissza, így a PATH.root() + 'tmp/a.txt' /project + tmp/a.txt = /projecttmp/a.txt lesz. Minden mappának saját segédfüggvénye van, amely hozzáadja az elválasztót.
exports.install = function() {
ROUTE('GET /wrong/path/', function($) {
$.json({ path: PATH.root() + 'tmp/a.txt' });
});
};exports.install = function() {
ROUTE('GET /right/path/', function($) {
$.json({ path: PATH.tmp('a.txt'), root: PATH.root() });
});
};Karakterlánc küldése egy szöveges módú WebSocket-útvonalon
A @text útvonalon a kapott üzenetek karakterláncok, de a send(message) továbbra is JSON-ként kódolja, amit küld, így a karakterlánc idézőjelekkel érkezik meg. A send(message, true) változtatás nélkül küldi el.
exports.install = function() {
ROUTE('SOCKET /wrong/text/ @text', function() {
this.on('message', function(client, message) {
client.send('echo: ' + message);
});
});
};exports.install = function() {
ROUTE('SOCKET /right/text/ @text', function() {
this.on('message', function(client, message) {
client.send('echo: ' + message, true);
});
});
};Azt várni, hogy a REQUEST() hibás állapotkódnál elutasít
A REQUEST() akkor is a válasszal teljesül, ha az állapotkód 404 vagy 500. Csak akkor utasít el, ha maga a kérés meghiúsul (a kapcsolat elutasítva, időtúllépés). Ellenőrizd a response.status értékét.
exports.install = function() {
ROUTE('GET /wrong/request/', async function($) {
try {
var response = await REQUEST({ url: $.hostname('/missing-page/') });
$.json({ ok: true, body: response.body.length > 0 });
} catch (e) {
$.json({ ok: false });
}
});
};exports.install = function() {
ROUTE('GET /right/request/', async function($) {
var response = await REQUEST({ url: $.hostname('/missing-page/') });
$.json({ ok: response.status < 400, status: response.status });
});
};exports.install = function() {
ROUTE('GET /where/', function($) {
$.json({ url: $.hostname('/') });
});
};{
"patch": {
"prompt": "Write a Total.js 5 action for a PATCH route that changes only the fields that were sent.",
"why": "Without `partial: true` a field that was not sent is filled with the default of its type (an empty string), and saving the model overwrites the stored value."
},
"route-flags": {
"prompt": "Write Total.js 5 routes that answer an AJAX request differently from a normal request on the same URL.",
"why": "A route without flags on a URL is checked before a route with flags on the same URL and takes every request, so the flagged route is never reached. Use one route and read `$.xhr` in the handler."
},
"extension-url": {
"prompt": "Write a Total.js 5 route that serves a URL with a file extension, such as /report.csv.",
"why": "A `GET` route never matches a URL with an extension; URLs such as `/report.csv` need a `FILE` route."
},
"cron-step": {
"prompt": "Write a Total.js 5 CRON line that runs every 15 minutes.",
"why": "Write the minutes as a list, for example `0,15,30,45`, so that the job runs exactly at those minutes."
},
"action-cache": {
"prompt": "Write a Total.js 5 action that keeps its answer for a minute so that the same request does not run it again.",
"why": "Keep the result of an action yourself with `CACHE`: `CACHE.set()` stores it and `CACHE.get()` reads it."
},
"folder": {
"prompt": "Where do I put code that must run when a Total.js 5 application starts?",
"why": "Total.js loads and runs the files of `definitions/`, `controllers/`, `actions/`, `schemas/`, `models/`, `modules/`, `extensions/` and `middleware/`. A file in `sources/`, `scripts/` or `transforms/` is not run."
},
"path": {
"prompt": "Write Total.js 5 code that builds the path of a file in the tmp folder.",
"why": "`PATH.root()` has no trailing slash, so joining text to it glues the names together. Use the helper of the folder: `PATH.tmp(name)`."
},
"socket-text": {
"prompt": "Write a Total.js 5 WebSocket route in @text mode that answers with a plain string.",
"why": "In a text route `send(message)` still encodes what it sends as JSON, so the string arrives with quotes. Pass `true` as the second argument to send it as it is."
},
"request-status": {
"prompt": "Write Total.js 5 code that calls another server with REQUEST() and handles an error answer such as 404.",
"why": "REQUEST() resolves with the answer even when the status is an error such as 404; it only rejects when the request itself fails. Check `response.status`."
}
}