Hola, mi nombre es Dmitry Karlovsky y ... me encanta copiar plantillas. Y en la interfaz, hay muchos conceptos erróneos sobre las plantillas. Así que vamos a romperlos en pedazos de abajo hacia arriba y de derecha a izquierda.
A continuación, veremos qué son las plantillas. Sus principales fortalezas y fatales debilidades. Por qué son necesarios y por qué no son necesarios. Nos formaremos una idea de la solución correcta y patinaremos por las populares. De modo que se nos proporciona toda la gama de sentimientos.
Por favor, ve a la mesa ...
¿Qué es una plantilla?
, : . , . , ..
:
"Hello, ${name}!"
:
"Hello" + name + "!"
, , — ? , , . , , .
XSLT:
<xsl:template name="page">
<acticle>
<h1>
<xsl:copy-of select="./head" />
</h1>
<xsl:copy-of select="./body" />
</article>
</xsl:template>
, 1 3 , , , , JSX-:
const head = <h1>{ headContent }</h1>
const body = 'Hello, World'
const article = <article>{ head }{ body }</article>
, , , , . , , , .
, JSX , . , HTML.
HTML?
HTML. HTML , DOM . HTML . .
, HTML, JSON, ProtoBuf . , DOM , JS-API, HTML . , DOM HTML, DOM.
, HAML:
!!! %html{ :lang => "ru" } %head %title= title %meta{ 'http-equiv' => 'Content-Type', :content => 'text/html' }/ %body %h1= title %p= description
! DOCTYPE html html @ lang \ru head title ? title meta @ content \text/html; charset=utf-8 @ http-equiv \Content-Type body h1 ? title p ? description
JSON. , .
HTML- , :
<!DOCTYPE html>
<html lang='ru'>
<head>
<title>{title}</title>
<meta
content='text/html; charset=utf-8'
http-equiv='Content-Type'
/>
</head>
<body>
<h1>{title}</h1>
<p>{description}</p>
</body>
</html>
HTML?
HTML DOM. . — . , .
HTML, DOM , . , .
"":
<bi-panel class="example">
<check-box
class="editable"
side="left"
[(checked)]="editable"
i18n
>
Editable
</check-box>
<text-area
#input
class="input"
side="left"
[(value)]="text"
[enabled]="editable"
placeholer="Markdown content.."
i18n-placeholder="Showed when input is empty"
/>
<div
*ngIf="text"
class="output-label"
side="right"
i18n
>
Result
</div>
<mark-down
*ngIf="text"
class="output"
side="right"
text="{{text}}"
/>
</bi-panel>
HTML, HTML, Angular-. DOM ( HTML) . , : , . , , , .
HTML. , :
#input
— , TS.class="editable"
— CSS.side="left"
— , .[(checked)]="editable"
— .[enabled]="editable"
— .text="{{text}}"
— .placeholer="Markdown content.."
— - .i18n-placeholder="Showed when input is empty"
— , , ,placeholder
, .*ngIf="text"
— , .
4 , , , . , HTML, . — , HTML. - , , , , , "" -, , .
HTML ?
HTML — . , "", . "" .
HTML . VR , . . . . , , , . . .
, , . , . — , , . , — . , — ", - , ".
:
_ = ()=> (
()=> ,
=> ( ) ,
_ => _( _ ),
__ => ( )( __ ),
_ => _( _ )
)
RDF:
_ _ _ _ _ _ _ __ __
. JSX, HTML, JS, , :
const Example = ( props: {
className?: string
text?: string
onTextChanged?: ( next: string )=> void
editable?: boolean
onEditableToggle?: ( next: boolean )=> void
} )=> {
const [ stateText, setStateText ] = useState( props.text ?? '' )
const [ stateEditable, setStateEditable ] = useState( props.editable ?? true )
const [ inputElement, setInputElement ] = useState< HTMLTextAreaElement >( null )
const className = ( props.className ?? '' ) + ' example'
const text = props.text ?? stateText
const editable = props.editable ?? stateEditable
const setText = useCallback( ( next: string )=> {
setStateText( next )
props.onTextChanged?.( next )
}, [ props.onTextChanged ] )
const setEditable = useCallback( ( next: boolean )=> {
setStateEditable( next )
props.onEditableToggle?.( next )
}, [ props.onEditableToggle ] )
return (
<BiPanel
className={ className }
left={
<>
<CheckBox
className="editable"
checked={ editable }
onToggle={ setEditable }
>
{ l10n( 'Editable' ) }
</CheckBox>
<TextArea
ref={ setInputElement }
className="input"
value={ text }
onChange={ setText }
enabled={ editable }
placeholder={ l10n( 'Markdown content..' ) }
/>
</>
}
right={
text
? <>
<div
className="output-label"
>
{ l10n( 'Result' ) }
</div>
<MarkDown
className="output"
text={ text }
/>
</>
: <></>
}
/>
)
}
. , ..
?
. AST, l10n
, , - , , .
,CheckBox.checked
,TextArea.enabled
props.editable
?
. , , , . , , checked={ editable } onToggle={ setEditable }
.
,editable
, ?
. data-flow . .
, CSS-.example .output .link
- ?
. .
, : . .
?
, . — . , . JS , . , "" JS. .
, , 2 :
- , .
- , .
"" "", , -, — .
$my_example $mol_view sub / <= Panel $my_bipanel left <= input / <= Editable $mol_check_box checked?val <=> editable?val true title @ \Editable <= Input $mol_textarea hint @ \Markdown content.. value?val <=> text?val \ enabled <= editable right <= output / <= Output_label $mol_paragraph sub / <= output_label @ \Result <= Output $mol_text text <= text
, JSX , , , . , , - . — , :
export class $my_example extends $.$my_example {
output() {
return this.text() ? super.output() : []
}
}
, - JSX , . , , -DSL HTML, .
JSX?
, , JSX ...
Push
, , . VDOM:
return (
<Dialog visible={ opened } >
{ ()=> <>Heavy content</> }
</Dialog>
)
, , "":
- .
- useCallback, .
- .
- VDOM API .
:
const dialogContent = useCallback( ()=> (
<>Heavy content</>
) )
return userObserver( ()=> (
<Dialog visible={ opened } >
{ dialogContent }
</Dialog>
) )
push pull — . pull: , , . push .
— , . — FireFox.
JSX . — . — useCallback , ( , - ):
const setName = useCallBack( ( name: string )=> {
setInfo({ ... info, name })
}, [ info, setInfo ] )
return <Input value={ info.name } onChange={ setName }>
, useCallback , info
, , , info.name
. Input
info
.
, . , , , .
- HTML , — :
<input type="password" minLength={ 5 } className={ 'password ' + className } />
:
<Dialog>
<Hello />
<World />
</Dialog>
<Dialog
children={[
<Hello />,
<World />,
]}
/>
— : HTML JS.
:
<Dialog>
<Hello />
{/* World */}
</Dialog>
<Dialog>
<Hello ref={ setHelloRef } />
<World ref={ setWorldRef } />
</Dialog>
, , . :
<Dialog>
<Message key="hello">Hello</Message>
<Message key="world">World</Message>
</Dialog>
, , .
, , , .
<ThemeContext.Provider value={theme} >
<UserContext.Provider value={signedInUser} >
<Layout />
</UserContext.Provider>
</ThemeContext.Provider>
<ThemeContext.Consumer>
{ theme => (
<UserContext.Consumer>
{ user => (
<ProfilePage user={user} theme={theme} />
) }
</UserContext.Consumer>
) }
</ThemeContext.Consumer>
, , . , , , , . , , , , , , :
<div className="tag-list">
{tags.map((tag) => (
<button
key={tag}
className="tag-pill tag-default"
onClick={() =>
dispatch({
type: 'SET_TAB',
tab: { type: 'TAG', label: tag },
})
}
>
{tag}
</button>
))}
</div>
, "" , , — . , , . , , ..
view.tree ?
, , , ..
IDE
Microsoft JSX TypeScript, , Language Server. VSCode, IDE.
, Microsoft TS. view.tree
, , TS, , IDE . , , . .
. , .
, null
any
:
/**
* Placeholder null
*/
Placeholder() {
return null as any
}
:
/**
* name!id?next \Unknown
*/
@ $mol_mem_key
name(id: any, next?: any) {
if ( next !== undefined ) return next as never
return "Unknown"
}
, . , , :
/**
* Placeholder null $mol_view
*/
Placeholder() {
return null as null | $mol_view
}
/**
* name!number?string \Unknown
*/
@ $mol_mem_key
name(id: number, next?: string) {
if ( next !== undefined ) return next
return "Unknown"
}
?
, . , , ..
"Tree — AST " tree
. " sourcemaps " . "$mol — " view.tree
.
, , , .