Gelişmiş
ContentBody ve ContentBlock
Birden çok bloğun birlikte doldurduğu gövde; ContentBody gövdesi, ContentBlock parçaları, birikme, serbest bırakma ve Transport'tan farkı.
Transport tek bir gönderenin içeriğini bir yuvada gösterir; ContentBody ise birden çok bloğun birlikte doldurduğu bir gövdedir. Layout'ta bir gövde açılır, sayfanın farklı yerlerindeki bloklar parçalarını oraya ekler ve parçalar gövdede birikir.
Kullanım
Örnekte layout'un alt çubuğu bir gövde açar; klasör listesi toplam not sayısını, not sayfası açık notun düzenlenme zamanını oraya ekler. Gövde:
import { Component, ContentBody } from "@motifx/core";
export class StatusBar extends Component<HTMLElement> {
static override elementTag = "footer";
override onConfigured() {
this.class.add("statusbar");
}
override view() {
return <ContentBody name="status" />;
}
}
import { Component, ContentBody } from "@motifx/core";
export class StatusBar extends Component<HTMLElement> {
static override elementTag = "footer";
override onConfigured() {
this.class.add("statusbar");
}
override view() {
return new ContentBody({ name: "status" });
}
}
import { ContentBody } from "@motifx/core";
export function StatusBar() {
return (
<footer class="statusbar">
<ContentBody name="status" />
</footer>
);
}
import { ComponentBase, ContentBody, motifComponent } from "@motifx/core";
export function StatusBar() {
return motifComponent("footer", (footer: ComponentBase) => {
footer.class.add("statusbar");
footer.controls.add(new ContentBody({ name: "status" }));
});
}
import { ContentBody, motifOptions } from "@motifx/core";
export const StatusBar = () => motifOptions({
el: "footer",
onConfigured() {
this.class.add("statusbar");
},
view() {
return <ContentBody name="status" />;
},
});
import { ContentBody, motifOptions } from "@motifx/core";
export const StatusBar = () => motifOptions({
el: "footer",
onConfigured() {
this.class.add("statusbar");
},
view() {
return new ContentBody({ name: "status" });
},
});
import { Component, ContentBody } from "@motifx/core";
export class StatusBar extends Component {
static elementTag = "footer";
onConfigured() {
this.class.add("statusbar");
}
view() {
return <ContentBody name="status" />;
}
}
import { Component, ContentBody } from "@motifx/core";
export class StatusBar extends Component {
static elementTag = "footer";
onConfigured() {
this.class.add("statusbar");
}
view() {
return new ContentBody({ name: "status" });
}
}
import { ContentBody } from "@motifx/core";
export function StatusBar() {
return (
<footer class="statusbar">
<ContentBody name="status" />
</footer>
);
}
import { ContentBody, motifComponent } from "@motifx/core";
export function StatusBar() {
return motifComponent("footer", (footer) => {
footer.class.add("statusbar");
footer.controls.add(new ContentBody({ name: "status" }));
});
}
import { ContentBody, motifOptions } from "@motifx/core";
export const StatusBar = () => motifOptions({
el: "footer",
onConfigured() {
this.class.add("statusbar");
},
view() {
return <ContentBody name="status" />;
},
});
import { ContentBody, motifOptions } from "@motifx/core";
export const StatusBar = () => motifOptions({
el: "footer",
onConfigured() {
this.class.add("statusbar");
},
view() {
return new ContentBody({ name: "status" });
},
});
Bloklar:
import { Component, ContentBlock } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";
export class CountStatus extends Component {
notes = this.getService(NotesService)!;
override view() {
return (
<ContentBlock target="status">
<span>{() => `${this.notes.count("notes")} not`}</span>
</ContentBlock>
);
}
}
export class EditedStatus extends Component<any, { note: Note }> {
override view() {
const { note } = this.props;
return (
<ContentBlock target="status">
<span>{() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`}</span>
</ContentBlock>
);
}
}
import { Component, ComponentBase, ContentBlock, motifComponent } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";
export class CountStatus extends Component {
notes = this.getService(NotesService)!;
override view() {
const count = motifComponent("span", (span: ComponentBase) => span.bindings.text(() => `${this.notes.count("notes")} not`));
return motifComponent(ContentBlock, { target: "status", childs: [count] });
}
}
export class EditedStatus extends Component<any, { note: Note }> {
override view() {
const { note } = this.props;
const edited = motifComponent("span", (span: ComponentBase) => span.bindings.text(() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`));
return motifComponent(ContentBlock, { target: "status", childs: [edited] });
}
}
import { ContentBlock, FromService } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";
export function CountStatus() {
const notes = FromService(NotesService)!;
return (
<ContentBlock target="status">
<span>{() => `${notes.count("notes")} not`}</span>
</ContentBlock>
);
}
export function EditedStatus(props: { note: Note }) {
const { note } = props;
return (
<ContentBlock target="status">
<span>{() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`}</span>
</ContentBlock>
);
}
import { ComponentBase, ContentBlock, FromService, motifComponent } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";
export function CountStatus() {
const notes = FromService(NotesService)!;
const count = motifComponent("span", (span: ComponentBase) => span.bindings.text(() => `${notes.count("notes")} not`));
return motifComponent(ContentBlock, { target: "status", childs: [count] });
}
export function EditedStatus(props: { note: Note }) {
const { note } = props;
const edited = motifComponent("span", (span: ComponentBase) => span.bindings.text(() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`));
return motifComponent(ContentBlock, { target: "status", childs: [edited] });
}
import { ContentBlock, motifOptions } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";
export const CountStatus = () => motifOptions({
el: null,
view() {
const notes = this.getService(NotesService)!;
return (
<ContentBlock target="status">
<span>{() => `${notes.count("notes")} not`}</span>
</ContentBlock>
);
},
});
export const EditedStatus = (props: { note: Note }) => motifOptions({
el: null,
view() {
const { note } = props;
return (
<ContentBlock target="status">
<span>{() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`}</span>
</ContentBlock>
);
},
});
import { ComponentBase, ContentBlock, motifComponent, motifOptions } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";
export const CountStatus = () => motifOptions({
el: null,
view() {
const notes = this.getService(NotesService)!;
const count = motifComponent("span", (span: ComponentBase) => span.bindings.text(() => `${notes.count("notes")} not`));
return motifComponent(ContentBlock, { target: "status", childs: [count] });
},
});
export const EditedStatus = (props: { note: Note }) => motifOptions({
el: null,
view() {
const { note } = props;
const edited = motifComponent("span", (span: ComponentBase) => span.bindings.text(() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`));
return motifComponent(ContentBlock, { target: "status", childs: [edited] });
},
});
import { Component, ContentBlock } from "@motifx/core";
import { NotesService } from "../services/notes";
export class CountStatus extends Component {
notes = this.getService(NotesService);
view() {
return (
<ContentBlock target="status">
<span>{() => `${this.notes.count("notes")} not`}</span>
</ContentBlock>
);
}
}
export class EditedStatus extends Component {
view() {
const { note } = this.props;
return (
<ContentBlock target="status">
<span>{() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`}</span>
</ContentBlock>
);
}
}
import { Component, ContentBlock, motifComponent } from "@motifx/core";
import { NotesService } from "../services/notes";
export class CountStatus extends Component {
notes = this.getService(NotesService);
view() {
const count = motifComponent("span", (span) => span.bindings.text(() => `${this.notes.count("notes")} not`));
return motifComponent(ContentBlock, { target: "status", childs: [count] });
}
}
export class EditedStatus extends Component {
view() {
const { note } = this.props;
const edited = motifComponent("span", (span) => span.bindings.text(() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`));
return motifComponent(ContentBlock, { target: "status", childs: [edited] });
}
}
import { ContentBlock, FromService } from "@motifx/core";
import { NotesService } from "../services/notes";
export function CountStatus() {
const notes = FromService(NotesService);
return (
<ContentBlock target="status">
<span>{() => `${notes.count("notes")} not`}</span>
</ContentBlock>
);
}
export function EditedStatus(props) {
const { note } = props;
return (
<ContentBlock target="status">
<span>{() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`}</span>
</ContentBlock>
);
}
import { ContentBlock, FromService, motifComponent } from "@motifx/core";
import { NotesService } from "../services/notes";
export function CountStatus() {
const notes = FromService(NotesService);
const count = motifComponent("span", (span) => span.bindings.text(() => `${notes.count("notes")} not`));
return motifComponent(ContentBlock, { target: "status", childs: [count] });
}
export function EditedStatus(props) {
const { note } = props;
const edited = motifComponent("span", (span) => span.bindings.text(() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`));
return motifComponent(ContentBlock, { target: "status", childs: [edited] });
}
import { ContentBlock, motifOptions } from "@motifx/core";
import { NotesService } from "../services/notes";
export const CountStatus = () => motifOptions({
el: null,
view() {
const notes = this.getService(NotesService);
return (
<ContentBlock target="status">
<span>{() => `${notes.count("notes")} not`}</span>
</ContentBlock>
);
},
});
export const EditedStatus = (props) => motifOptions({
el: null,
view() {
const { note } = props;
return (
<ContentBlock target="status">
<span>{() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`}</span>
</ContentBlock>
);
},
});
import { ContentBlock, motifComponent, motifOptions } from "@motifx/core";
import { NotesService } from "../services/notes";
export const CountStatus = () => motifOptions({
el: null,
view() {
const notes = this.getService(NotesService);
const count = motifComponent("span", (span) => span.bindings.text(() => `${notes.count("notes")} not`));
return motifComponent(ContentBlock, { target: "status", childs: [count] });
},
});
export const EditedStatus = (props) => motifOptions({
el: null,
view() {
const { note } = props;
const edited = motifComponent("span", (span) => span.bindings.text(() => `Düzenlendi ${new Date(note.updatedAt).toLocaleString("tr-TR")}`));
return motifComponent(ContentBlock, { target: "status", childs: [edited] });
},
});
Layout alt çubuğu <StatusBar /> ile, klasör listesi <CountStatus /> ile, not sayfası <EditedStatus note={note} /> ile yerleştirir.
Layout alt çubuğu new StatusBar(), klasör listesi new CountStatus(), not sayfası new EditedStatus({ note }) ile yerleştirir.
Layout alt çubuğu motifComponent(StatusBar), klasör listesi motifComponent(CountStatus), not sayfası motifComponent(EditedStatus, { note }) ile yerleştirir.
ContentBody ve ContentBlock çekirdeğin sınıflarıdır. JSX'siz yazımda gövde new ContentBody({ name }), blok derleyicinin ürettiği gibi motifComponent(ContentBlock, { target, childs }) ile kurulur.
Not sayfası açıkken çubukta iki parça yan yana durur: not sayısı ve düzenlenme zamanı. İkisi de yazıldıkları bileşenin bağıyla güncellenir. Sayfa kapanınca yalnız onun parçası gider; klasör listesinin parçası kalır.
Prop'lar
| Bileşen | Prop | Açıklama |
|---|---|---|
ContentBody |
name |
Gövdenin adı. Aynı adla ikinci bir gövde kurulursa yeni bloklar ona gider; eski gövdenin sonradan serbest bırakılması yeni gövdenin kaydını bozmaz. |
ContentBlock |
target |
Parçaların ekleneceği gövdenin adı. |
Davranış
- İkisi de fragment köklüdür; bulundukları yere eleman eklemezler.
- Hedef gövde varken blok çocuklarını kendisi kurmaz: eklenen her çocuk (blokla birlikte verilen
childsve sonradancontrols.addile gelenler) o anda gövdenincontrols'una taşınır ve orada kurulur; ebeveyni gövde olur.childsbloğun yapıcısında, blok kurulmadan taşınır. Bloğuncontroladdedolayı her çocuk için tetiklenir. - Gövde henüz yoksa, blok kurulurken elinde olan çocuklar blokla birlikte kurulur ve bloğun yerinde görünür; blok kurulduktan sonra
controls.addile eklenenler kurulmadan bekler. Aynı adlı gövde oluşturulduğu anda hepsi gövdeye taşınır; son yerleşim sıradan bağımsızdır. - Parçalar gövdede birikir; her blok yalnız kendi eklediği parçaları bilir. Blok serbest bırakılınca gövdedeki kendi parçalarını kaldırır ve serbest bırakır (geliştirme modunda her parça için
MJX109uyarısı yazılır); diğer blokların parçaları kalır. - Gövde serbest bırakılınca içindeki bütün parçalar onunla serbest bırakılır; bloklar bilgilendirilmez, aynı adla yeni bir gövde kurulsa da parçalar geri gelmez.
- Taşınan parçaların bağları ve olay işleyicileri yazıldıkları bileşenin durumuyla çalışmaya devam eder.
- Gövde ile bloklar uygulamanın olayıyla haberleşir; bu yüzden kurulmuş bir
Applicationiçinde kullanılırlar. Uygulama kurulmadan oluşturulan gövde hata verir.
Transport ile karşılaştırma
Transport / TransportTo |
ContentBody / ContentBlock |
|
|---|---|---|
| Amaç | Bir gönderenin içeriğini yuvada göstermek | Birçok bloğun parçalarını gövdede biriktirmek |
| Birden çok kaynak | mode: 'replace' sonuncuyu bırakır; 'merge' birleştirir |
Her zaman birikir |
| Gönderen serbest bırakılınca | Kendi içeriğini kaldırır | Kendi parçalarını kaldırır (MJX109) |
| Yerleşim | Yuva fragment, gönderen boş <div> bırakır |
İkisi de fragment |
Sonraki adım
Büyük listeleri sanal kaydırmayla göstermek için Sanal Listeler (Virtualization) bölümüne geçin. Tek gönderenli yuva ve programatik taşıma için Transport ve TransportTo; bileşen ağacının temelleri için Bileşenler.