595 lines
27 KiB
HTML
595 lines
27 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="en">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>TabData Complete Breakdown</title>
|
|||
|
|
<style>
|
|||
|
|
* {
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|||
|
|
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
|||
|
|
padding: 20px;
|
|||
|
|
line-height: 1.8;
|
|||
|
|
font-size: 17px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.container {
|
|||
|
|
max-width: 1300px;
|
|||
|
|
margin: 0 auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1 {
|
|||
|
|
text-align: center;
|
|||
|
|
color: white;
|
|||
|
|
font-size: 2.5em;
|
|||
|
|
margin-bottom: 30px;
|
|||
|
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section {
|
|||
|
|
background: white;
|
|||
|
|
border-radius: 12px;
|
|||
|
|
padding: 30px;
|
|||
|
|
margin-bottom: 25px;
|
|||
|
|
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-title {
|
|||
|
|
font-size: 2em;
|
|||
|
|
color: #0175C2;
|
|||
|
|
margin-bottom: 20px;
|
|||
|
|
border-bottom: 4px solid #0175C2;
|
|||
|
|
padding-bottom: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.code {
|
|||
|
|
background: #1e1e1e;
|
|||
|
|
color: #d4d4d4;
|
|||
|
|
padding: 20px;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
font-family: 'Courier New', monospace;
|
|||
|
|
overflow-x: auto;
|
|||
|
|
margin: 20px 0;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
font-size: 15px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.keyword { color: #569cd6; font-weight: bold; }
|
|||
|
|
.string { color: #ce9178; }
|
|||
|
|
.comment { color: #6a9955; }
|
|||
|
|
.class { color: #4ec9b0; }
|
|||
|
|
.function { color: #dcdcaa; }
|
|||
|
|
.number { color: #b5cea8; }
|
|||
|
|
|
|||
|
|
.line-box {
|
|||
|
|
background: #f8f9fa;
|
|||
|
|
border-left: 6px solid #0175C2;
|
|||
|
|
padding: 25px;
|
|||
|
|
margin: 25px 0;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.line-number {
|
|||
|
|
background: #0175C2;
|
|||
|
|
color: white;
|
|||
|
|
padding: 6px 15px;
|
|||
|
|
border-radius: 20px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
display: inline-block;
|
|||
|
|
margin-bottom: 15px;
|
|||
|
|
font-size: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.part-title {
|
|||
|
|
font-size: 1.5em;
|
|||
|
|
color: #0175C2;
|
|||
|
|
margin: 20px 0 15px 0;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.info-box {
|
|||
|
|
background: #e3f2fd;
|
|||
|
|
border-left: 5px solid #2196f3;
|
|||
|
|
padding: 20px;
|
|||
|
|
margin: 20px 0;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.important-box {
|
|||
|
|
background: #fff3cd;
|
|||
|
|
border-left: 5px solid #ffc107;
|
|||
|
|
padding: 20px;
|
|||
|
|
margin: 20px 0;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.connection-diagram {
|
|||
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|||
|
|
color: white;
|
|||
|
|
padding: 30px;
|
|||
|
|
border-radius: 12px;
|
|||
|
|
margin: 30px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.arrow {
|
|||
|
|
text-align: center;
|
|||
|
|
font-size: 2.5em;
|
|||
|
|
color: #0175C2;
|
|||
|
|
margin: 15px 0;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.example-box {
|
|||
|
|
background: #e8f5e9;
|
|||
|
|
border: 2px solid #4caf50;
|
|||
|
|
padding: 20px;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
margin: 20px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.inline-code {
|
|||
|
|
background: #f5f5f5;
|
|||
|
|
padding: 3px 8px;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
font-family: 'Courier New', monospace;
|
|||
|
|
color: #d63384;
|
|||
|
|
font-size: 0.95em;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.three-parts {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|||
|
|
gap: 20px;
|
|||
|
|
margin: 30px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.part-box {
|
|||
|
|
background: white;
|
|||
|
|
border: 3px solid #0175C2;
|
|||
|
|
padding: 20px;
|
|||
|
|
border-radius: 12px;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.part-box h3 {
|
|||
|
|
color: #0175C2;
|
|||
|
|
margin-bottom: 15px;
|
|||
|
|
font-size: 1.3em;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.flow-step {
|
|||
|
|
background: white;
|
|||
|
|
border: 2px solid #0175C2;
|
|||
|
|
border-radius: 8px;
|
|||
|
|
padding: 20px;
|
|||
|
|
margin: 15px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.highlight {
|
|||
|
|
background: #fff3cd;
|
|||
|
|
padding: 3px 8px;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
table {
|
|||
|
|
width: 100%;
|
|||
|
|
border-collapse: collapse;
|
|||
|
|
margin: 20px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
th {
|
|||
|
|
background: #0175C2;
|
|||
|
|
color: white;
|
|||
|
|
padding: 15px;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
td {
|
|||
|
|
padding: 15px;
|
|||
|
|
border-bottom: 1px solid #ddd;
|
|||
|
|
background: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
tr:hover td {
|
|||
|
|
background: #f8f9fa;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 900px) {
|
|||
|
|
.three-parts {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="container">
|
|||
|
|
<h1>📚 Complete TabData Breakdown</h1>
|
|||
|
|
|
|||
|
|
<!-- SECTION 1: The Three Main Parts -->
|
|||
|
|
<div class="section">
|
|||
|
|
<h2 class="section-title">🎯 The Three Main Parts</h2>
|
|||
|
|
|
|||
|
|
<p style="font-size: 1.2em; margin-bottom: 25px;">
|
|||
|
|
Your TabData class has <strong>THREE</strong> main sections. Let's understand what each one is called and what it does:
|
|||
|
|
</p>
|
|||
|
|
|
|||
|
|
<div class="three-parts">
|
|||
|
|
<div class="part-box" style="border-color: #f44336;">
|
|||
|
|
<h3>Part 1️⃣</h3>
|
|||
|
|
<h4 style="color: #f44336; margin: 15px 0;">CLASS DEFINITION</h4>
|
|||
|
|
<div class="code" style="font-size: 13px; text-align: left;">
|
|||
|
|
<span class="keyword">class</span> <span class="class">TabData</span> {
|
|||
|
|
<span class="class">String</span> id;
|
|||
|
|
<span class="class">String</span> title;
|
|||
|
|
<span class="comment">// ... properties</span>
|
|||
|
|
}</div>
|
|||
|
|
<p style="margin-top: 15px;">Declares the class and its <strong>properties</strong> (variables)</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="part-box" style="border-color: #4caf50;">
|
|||
|
|
<h3>Part 2️⃣</h3>
|
|||
|
|
<h4 style="color: #4caf50; margin: 15px 0;">REGULAR CONSTRUCTOR</h4>
|
|||
|
|
<div class="code" style="font-size: 13px; text-align: left;">
|
|||
|
|
<span class="class">TabData</span>({
|
|||
|
|
<span class="keyword">required this</span>.id,
|
|||
|
|
<span class="comment">// ... parameters</span>
|
|||
|
|
})</div>
|
|||
|
|
<p style="margin-top: 15px;">The <strong>default way</strong> to create TabData objects</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="part-box" style="border-color: #2196f3;">
|
|||
|
|
<h3>Part 3️⃣</h3>
|
|||
|
|
<h4 style="color: #2196f3; margin: 15px 0;">FACTORY CONSTRUCTOR</h4>
|
|||
|
|
<div class="code" style="font-size: 13px; text-align: left;">
|
|||
|
|
<span class="keyword">factory</span> <span class="class">TabData</span>.<span class="function">fromJson</span>(
|
|||
|
|
<span class="class">Map</span> json
|
|||
|
|
) => <span class="class">TabData</span>(...)</div>
|
|||
|
|
<p style="margin-top: 15px;">A <strong>special way</strong> to create TabData from JSON</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="connection-diagram">
|
|||
|
|
<h3 style="margin-bottom: 20px; font-size: 1.5em;">🔗 How They Connect:</h3>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<strong>1. Class Definition</strong> defines WHAT a TabData object IS
|
|||
|
|
<div style="margin-top: 10px; padding-left: 20px;">
|
|||
|
|
→ "A TabData has an id, title, url, etc."
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="arrow">⬇️</div>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<strong>2. Regular Constructor</strong> creates TabData objects manually
|
|||
|
|
<div style="margin-top: 10px; padding-left: 20px;">
|
|||
|
|
→ <span class="inline-code" style="background: #555;">TabData(id: '123', title: 'Test', ...)</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="arrow">⬇️</div>
|
|||
|
|
<div class="flow-step">
|
|||
|
|
<strong>3. Factory Constructor</strong> ALSO creates TabData objects, but from JSON
|
|||
|
|
<div style="margin-top: 10px; padding-left: 20px;">
|
|||
|
|
→ <span class="inline-code" style="background: #555;">TabData.fromJson({'id': '123', 'title': 'Test'})</span>
|
|||
|
|
</div>
|
|||
|
|
<div style="margin-top: 10px; padding-left: 20px;">
|
|||
|
|
→ Internally, it calls the Regular Constructor!
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- SECTION 2: Part 1 - Class Definition -->
|
|||
|
|
<div class="section">
|
|||
|
|
<h2 class="section-title">Part 1️⃣: Class Definition & Properties</h2>
|
|||
|
|
|
|||
|
|
<div class="line-box">
|
|||
|
|
<div class="line-number">Line 1</div>
|
|||
|
|
<div class="code">
|
|||
|
|
<span class="keyword">class</span> <span class="class">TabData</span> {</div>
|
|||
|
|
|
|||
|
|
<div class="part-title">🔍 Breaking It Down:</div>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li><span class="inline-code">class</span> - Keyword that declares a new class</li>
|
|||
|
|
<li><span class="inline-code">TabData</span> - The name of our class</li>
|
|||
|
|
<li><span class="inline-code">{</span> - Opening brace, starts the class body</li>
|
|||
|
|
</ul>
|
|||
|
|
|
|||
|
|
<div class="info-box" style="margin-top: 20px;">
|
|||
|
|
<strong>What is a class?</strong> A class is a <strong>blueprint</strong> or <strong>template</strong> for creating objects. Like a cookie cutter - the class is the cutter, and each TabData object is a cookie made from it.
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="example-box">
|
|||
|
|
<strong>📝 Official Name:</strong> "Class Declaration"
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="line-box">
|
|||
|
|
<div class="line-number">Lines 2-10</div>
|
|||
|
|
<div class="code">
|
|||
|
|
<span class="class">String</span> id;
|
|||
|
|
<span class="class">String</span> title;
|
|||
|
|
<span class="class">String</span> url;
|
|||
|
|
<span class="class">String</span> favicon;
|
|||
|
|
<span class="class">DateTime</span> lastAccessed;
|
|||
|
|
<span class="keyword">bool</span> isPinned;
|
|||
|
|
<span class="class">String</span> type;
|
|||
|
|
<span class="keyword">int</span>? visitCount;
|
|||
|
|
<span class="class">String</span>? folder;</div>
|
|||
|
|
|
|||
|
|
<div class="part-title">🔍 What These Are:</div>
|
|||
|
|
<p>These are called <strong>properties</strong>, <strong>fields</strong>, or <strong>instance variables</strong>.</p>
|
|||
|
|
|
|||
|
|
<p style="margin-top: 15px;"><strong>They define what data each TabData object will store.</strong></p>
|
|||
|
|
|
|||
|
|
<table style="margin-top: 20px;">
|
|||
|
|
<tr>
|
|||
|
|
<th>Line</th>
|
|||
|
|
<th>Property Name</th>
|
|||
|
|
<th>Type</th>
|
|||
|
|
<th>Can be null?</th>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>2</td>
|
|||
|
|
<td><code>id</code></td>
|
|||
|
|
<td>String</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>3</td>
|
|||
|
|
<td><code>title</code></td>
|
|||
|
|
<td>String</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>4</td>
|
|||
|
|
<td><code>url</code></td>
|
|||
|
|
<td>String</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>5</td>
|
|||
|
|
<td><code>favicon</code></td>
|
|||
|
|
<td>String</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>6</td>
|
|||
|
|
<td><code>lastAccessed</code></td>
|
|||
|
|
<td>DateTime</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>7</td>
|
|||
|
|
<td><code>isPinned</code></td>
|
|||
|
|
<td>bool</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>8</td>
|
|||
|
|
<td><code>type</code></td>
|
|||
|
|
<td>String</td>
|
|||
|
|
<td>❌ No</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>9</td>
|
|||
|
|
<td><code>visitCount</code></td>
|
|||
|
|
<td>int<strong>?</strong></td>
|
|||
|
|
<td>✅ Yes (the <strong>?</strong> means nullable)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td>10</td>
|
|||
|
|
<td><code>folder</code></td>
|
|||
|
|
<td>String<strong>?</strong></td>
|
|||
|
|
<td>✅ Yes (the <strong>?</strong> means nullable)</td>
|
|||
|
|
</tr>
|
|||
|
|
</table>
|
|||
|
|
|
|||
|
|
<div class="example-box">
|
|||
|
|
<strong>📝 Official Name:</strong> "Instance Variables" or "Properties" or "Fields"
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- SECTION 3: Part 2 - Regular Constructor -->
|
|||
|
|
<div class="section">
|
|||
|
|
<h2 class="section-title">Part 2️⃣: Regular Constructor</h2>
|
|||
|
|
|
|||
|
|
<div class="line-box">
|
|||
|
|
<div class="line-number">Line 12</div>
|
|||
|
|
<div class="code">
|
|||
|
|
<span class="class">TabData</span>({</div>
|
|||
|
|
|
|||
|
|
<div class="part-title">🔍 What This Is:</div>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li><span class="inline-code">TabData</span> - Constructor name (same as class name)</li>
|
|||
|
|
<li><span class="inline-code">(</span> - Opens parameter list</li>
|
|||
|
|
<li><span class="inline-code">{</span> - Curly brace means "named parameters"</li>
|
|||
|
|
</ul>
|
|||
|
|
|
|||
|
|
<div class="important-box" style="margin-top: 20px;">
|
|||
|
|
<strong>🎯 This is called:</strong> "Default Constructor" or "Regular Constructor" or "Named Parameter Constructor"
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="info-box">
|
|||
|
|
<strong>What does a constructor do?</strong> A constructor is a special method that <strong>creates and initializes</strong> new objects. When you write <span class="inline-code">TabData(...)</span>, this constructor runs.
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="line-box">
|
|||
|
|
<div class="line-number">Lines 13-21</div>
|
|||
|
|
<div class="code">
|
|||
|
|
<span class="keyword">required this</span>.id, <span class="comment">// Line 13</span>
|
|||
|
|
<span class="keyword">required this</span>.title, <span class="comment">// Line 14</span>
|
|||
|
|
<span class="keyword">required this</span>.url, <span class="comment">// Line 15</span>
|
|||
|
|
<span class="keyword">this</span>.favicon = <span class="string">''</span>, <span class="comment">// Line 16</span>
|
|||
|
|
<span class="class">DateTime</span>? lastAccessed, <span class="comment">// Line 17</span>
|
|||
|
|
<span class="keyword">this</span>.isPinned = <span class="keyword">false</span>, <span class="comment">// Line 18</span>
|
|||
|
|
<span class="keyword">this</span>.type = <span class="string">'tab'</span>, <span class="comment">// Line 19</span>
|
|||
|
|
<span class="keyword">this</span>.visitCount, <span class="comment">// Line 20</span>
|
|||
|
|
<span class="keyword">this</span>.folder, <span class="comment">// Line 21</span></div>
|
|||
|
|
|
|||
|
|
<div class="part-title">🔍 Each Line Explained:</div>
|
|||
|
|
|
|||
|
|
<div style="background: #ffebee; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<strong>Lines 13-15:</strong> <span class="inline-code">required this.id</span>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li><span class="inline-code">required</span> = MUST be provided</li>
|
|||
|
|
<li><span class="inline-code">this.id</span> = assign parameter value to the <span class="inline-code">id</span> property</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #e8f5e9; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<strong>Line 16:</strong> <span class="inline-code">this.favicon = ''</span>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li>Optional parameter (no <span class="inline-code">required</span>)</li>
|
|||
|
|
<li>Has default value: empty string <span class="inline-code">''</span></li>
|
|||
|
|
<li>If not provided → uses <span class="inline-code">''</span></li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #fff3e0; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<strong>Line 17:</strong> <span class="inline-code">DateTime? lastAccessed</span>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li><strong>NOT</strong> <span class="inline-code">this.lastAccessed</span> - just the parameter name!</li>
|
|||
|
|
<li>The <span class="inline-code">?</span> means it can be null</li>
|
|||
|
|
<li>This is handled specially in the initializer list (line 22)</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #e1f5fe; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<strong>Lines 18-19:</strong> <span class="inline-code">this.isPinned = false</span>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li>Optional with defaults</li>
|
|||
|
|
<li><span class="inline-code">isPinned</span> defaults to <span class="inline-code">false</span></li>
|
|||
|
|
<li><span class="inline-code">type</span> defaults to <span class="inline-code">'tab'</span></li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #f3e5f5; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<strong>Lines 20-21:</strong> <span class="inline-code">this.visitCount</span>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li>Optional, no default value</li>
|
|||
|
|
<li>If not provided → becomes <span class="inline-code">null</span></li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="example-box">
|
|||
|
|
<strong>📝 Official Name:</strong> "Constructor Parameters"
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="line-box" style="background: #fff3e0; border-color: #ff9800;">
|
|||
|
|
<div class="line-number" style="background: #ff9800;">Line 22</div>
|
|||
|
|
<div class="code">
|
|||
|
|
}) : lastAccessed = lastAccessed ?? <span class="class">DateTime</span>.<span class="function">now</span>();</div>
|
|||
|
|
|
|||
|
|
<div class="part-title" style="color: #e65100;">🔍 The Most Important Line!</div>
|
|||
|
|
|
|||
|
|
<p style="font-size: 1.1em; margin: 15px 0;">Let's break this into 4 parts:</p>
|
|||
|
|
|
|||
|
|
<div style="background: white; padding: 20px; border-radius: 8px; margin: 15px 0;">
|
|||
|
|
<h4 style="color: #ff9800;">Part 1: <span class="inline-code">}</span></h4>
|
|||
|
|
<p>Closes the parameter list</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: white; padding: 20px; border-radius: 8px; margin: 15px 0;">
|
|||
|
|
<h4 style="color: #ff9800;">Part 2: <span class="inline-code">:</span></h4>
|
|||
|
|
<p>Starts the <strong>initializer list</strong></p>
|
|||
|
|
<p style="margin-top: 10px;">The initializer list runs <strong>BEFORE</strong> the object is created. It's for special initialization logic.</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: white; padding: 20px; border-radius: 8px; margin: 15px 0;">
|
|||
|
|
<h4 style="color: #ff9800;">Part 3: <span class="inline-code">lastAccessed = lastAccessed</span></h4>
|
|||
|
|
<p>Left side: <span class="inline-code">lastAccessed</span> → the property (same as <span class="inline-code">this.lastAccessed</span>)</p>
|
|||
|
|
<p>Right side: <span class="inline-code">lastAccessed</span> → the parameter from line 17</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: white; padding: 20px; border-radius: 8px; margin: 15px 0;">
|
|||
|
|
<h4 style="color: #ff9800;">Part 4: <span class="inline-code">?? DateTime.now()</span></h4>
|
|||
|
|
<p><span class="inline-code">??</span> = "if null, use this instead"</p>
|
|||
|
|
<p><span class="inline-code">DateTime.now()</span> = current date/time</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="important-box" style="margin-top: 20px;">
|
|||
|
|
<h4>🎯 In Plain English:</h4>
|
|||
|
|
<p style="font-size: 1.1em; line-height: 2; margin-top: 10px;">
|
|||
|
|
"Set <span class="inline-code">this.lastAccessed</span> (the property) to the value of <span class="inline-code">lastAccessed</span> (the parameter),
|
|||
|
|
BUT if the parameter is null, use <span class="inline-code">DateTime.now()</span> instead"
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="example-box">
|
|||
|
|
<strong>📝 Official Names:</strong>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li>The <span class="inline-code">:</span> part is called an <strong>"Initializer List"</strong></li>
|
|||
|
|
<li>The <span class="inline-code">??</span> operator is called the <strong>"Null-Coalescing Operator"</strong></li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- SECTION 4: Part 3 - Factory Constructor -->
|
|||
|
|
<div class="section">
|
|||
|
|
<h2 class="section-title">Part 3️⃣: Factory Constructor (fromJson)</h2>
|
|||
|
|
|
|||
|
|
<div class="line-box">
|
|||
|
|
<div class="line-number">Line 25</div>
|
|||
|
|
<div class="code">
|
|||
|
|
<span class="keyword">factory</span> <span class="class">TabData</span>.<span class="function">fromJson</span>(<span class="class">Map</span><<span class="class">String</span>, <span class="keyword">dynamic</span>> json) => <span class="class">TabData</span>(</div>
|
|||
|
|
|
|||
|
|
<div class="part-title">🔍 Breaking Down Each Part:</div>
|
|||
|
|
|
|||
|
|
<div style="background: #e8f5e9; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<h4><span class="inline-code">factory</span></h4>
|
|||
|
|
<p>Keyword that makes this a <strong>factory constructor</strong></p>
|
|||
|
|
<p style="margin-top: 10px;"><strong>What's special about factory?</strong> It can do logic/processing BEFORE creating the object. It can also return an existing object instead of creating a new one (though we don't do that here).</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #e3f2fd; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<h4><span class="inline-code">TabData.fromJson</span></h4>
|
|||
|
|
<p>This is a <strong>named constructor</strong></p>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li><span class="inline-code">TabData</span> = class name</li>
|
|||
|
|
<li><span class="inline-code">.</span> = dot separator</li>
|
|||
|
|
<li><span class="inline-code">fromJson</span> = name we chose for this constructor</li>
|
|||
|
|
</ul>
|
|||
|
|
<p style="margin-top: 15px;"><strong>Why "fromJson"?</strong> Because this constructor creates a TabData object FROM JSON data. You can have multiple constructors with different names!</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #fff3e0; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<h4><span class="inline-code">Map<String, dynamic> json</span></h4>
|
|||
|
|
<p>This is the parameter - a Map (like a dictionary)</p>
|
|||
|
|
<ul style="padding-left: 25px; margin-top: 10px;">
|
|||
|
|
<li><span class="inline-code">Map</span> = data type (key-value pairs)</li>
|
|||
|
|
<li><span class="inline-code"><String, dynamic></span> = keys are Strings, values can be anything</li>
|
|||
|
|
<li><span class="inline-code">json</span> = parameter name</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div style="background: #f3e5f5; padding: 15px; border-radius: 6px; margin: 15px 0;">
|
|||
|
|
<h4><span class="inline-code">=> TabData(</span></h4>
|
|||
|
|
<p><span class="inline-code">=></span> is called an "arrow function" or "expression body"</p>
|
|||
|
|
<p style="margin-top: 10px;"><strong>Meaning:</strong> "return the result of <span class="inline-code">TabData(...)</span>"</p>
|
|||
|
|
<p style="margin-top: 10px;">This factory constructor calls the regular constructor (Part 2) and returns the result!</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="example-box">
|
|||
|
|
<strong>📝 Official Name:</strong> "Factory Constructor" or "Named Factory Constructor"
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="line-box">
|
|||
|
|
<div class="line-number">Lines 26-37</div>
|
|||
|
|
<h3 style="margin-bottom: 15px;">Inside the Factory - Extracting Data from JSON</h3>
|
|||
|
|
|
|||
|
|
<p>Each line extracts data from the <span class="inline-code">json</span> Map and passes it to the regular constructor:</p>
|
|||
|
|
|
|||
|
|
<div class="code">
|
|||
|
|
id: json[<span class="string">'id'</span>].<span class="function">toString</span>(), <span class="comment">// Line 26</span>
|
|||
|
|
title: json[<span class="string">'title'</span>] ?? <span class="string">'Untitled'</span>, <span class="comment">// Line 27</span>
|
|||
|
|
url: json[<span class="string">'url'</span>] ?? <span class="string">''</span>,
|