| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
import van from "vanjs-core"
const { a , p , div , li , ul } = van . tags
// Reusable components can be just pure vanilla JavaScript functions.
// Here we capitalize the first letter to follow React conventions.
const Hello =
( ) =>
div (
p ( "Hello" ) ,
ul (
li ( "?️World" ) ,
li ( a ( { href : "https://vanjs.org/" } , "?VanJS" ) ) ,
) ,
)
van . add ( document . body , Hello ( ) )Essayez JSFiddle
module HelloApp
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
let a : Tag = tags?a
let p : Tag = tags?p
let div : Tag = tags?div
let ul : Tag = tags?ul
let li : Tag = tags?li
let Hello =
fun _ ->
div [
p [ " Hello " ]
ul [
li [ " ?️World " ]
li [ a [{| href = " https://vanjs.org/ " |}; " ?VanJS " ]]
]
]
add [ document.body ; Hello ()]
|> ignoreDémo
https://codepen.io/kentechgeek/pen/vwnovox
let Greeting : Tag =
fun list ->
let name : string = list [ 0 ]? name
div [ $ " Hello {name}! " ]
add [ document.body ; Greeting [{| name = " Ken " |}]]
|> ignore const Greeting : Component < { name : string } > =
( { name } ) =>
< div > Hello { name } ! </ div > ;
render ( ( ) => < Greeting name = "Ken" /> , document . body ) ; Le projet VanFS comprend un code de type dactylographié.
https://github.com/ken-okabe/vanfs/blob/main/van-api/ts/basic.ts
Code TS à des fins de conversion en utilisant JS Proxy:
// unary function ([a,b,c,...]) in F#
// -> n-ary function (a,b,c,...) in VanJS Ceci est sous le répertoire van-api qui est essentiel et nous ne voudrions pas le modifier pour que les choses fonctionnent.
Les utilisateurs doivent installer tout CSS ou composant Web requis.
Vanjs ne fournit pas le support d'installation spécifique BEAUSE Ce n'est qu'un vanillajs.
D'un autre côté, Vanfs clarifie le processus étape par étape comme ci-dessous:
Tout ce dont nous avons besoin pour personnaliser ou importer est situé dans le répertoire des imports Web.
import {
provideFluentDesignSystem ,
fluentCard ,
fluentCheckbox
} from "@fluentui/web-components" ;
provideFluentDesignSystem ( )
. register (
fluentCard ( )
) ;
provideFluentDesignSystem ( )
. register (
fluentCheckbox ( )
) ; export let cssURLs = [
"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200"
] ;Quoi qu'il en soit, tout le code requis du projet VanFS est compilé en un seul bundle Vanillajs à l'aide de Fable et Vite.
let bindT = < A , B >
( monadf : ( a : A ) => Timeline < B > ) =>
( timelineA : Timeline < A > ) : Timeline < B > => {
let timelineB = monadf ( timelineA . lastVal ) ;
let newFn = ( a : A ) => {
nextT ( monadf ( a ) . lastVal ) ( timelineB ) ;
return undefined ;
} ;
timelineA . lastFns = timelineA . lastFns . concat ( [ newFn ] ) ;
return timelineB ;
} ;Dans TypeScript, par rapport à Legacy JavaScript, une étape supplémentaire est nécessaire pour ajouter des signatures de type à toutes les variables, fonctions et paramètres. C'est souvent écrasant.
let bindT =
fun monadf timelineA ->
let timelineB = timelineA.lastVal |> monadf
let newFn =
fun a ->
timelineB
|> nextT ( a |> monadf ) .lastVal
|> ignore
timelineA.lastFns <- timelineA.lastFns @ [ newFn ]
timelineBLe code F # est beaucoup plus propre et plus lisible que le code TypeScript.
Dans F #, nous devons rarement ajouter des types manuellement grâce à sa puissante inférence de type. Cela fait que F # Development se sent similaire au codage javascript hérité.
En réalité, c'est bien plus que cela.
Alors que les programmeurs peuvent vouloir définir des types d'objets fondamentaux qui forment l'épine dorsale de leur code, dans d'autres endroits, si le compilateur F # avertit une demande d'annotations de type manuel, quelque chose ne va généralement pas .
Dans F #, si le compilateur ne peut pas déduire le type, il suggère souvent qu'il peut y avoir des incohérences mathématiques.
Dans TypeScript, si le compilateur ne peut pas déduire le type, il suggère souvent des limitations dans ses capacités d'inférence de type. Il est difficile de déterminer la cause précise du problème.
En conséquence, les programmeurs F # sont naturellement conduits à écrire du code mathématiquement cohérent et rigoureux; Malheureusement, cet avantage se produit rarement dans TypeScript.
F # est généralement reconnu comme fonctionnant sur le framework .NET, mais tout comme TypeScript est compilé en javascript, F # est également compilé en JavaScript.
TypeScript -> javascript
F # -> JavaScript
Plus précisément,
Typescirpt
⬇ Compiler de type TypeScript en cours d'exécution sur Node.js (npx tsc)
Javascript en cours d'exécution dans le navigateur
F #
⬇ compilateur fable fonctionnant sur .NET (dotnet fable)
Javascript en cours d'exécution dans le navigateur
Par conséquent, l'épine dorsale de Vanfs est fable.
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
.NET SDK
Node.js et NPM CLI ou alternatives (chignon / neo / yarn, etc.)
Si vous êtes nouveau sur F # et utilisez VScode, lisez les paramètres F # sur VScode.
Un projet Vanfs / Fable est un hybride du projet F # .NET et du projet NPM .
Voir Fable Configuration Documentaion
git clone https://github.com/ken-okabe/vanfs
cd vanfs
dotnet restore # .NET project setup
dotnet tool restore
npm i # npm project setup body {
font-family : sans-serif;
padding : 1 em ;
background-color : beige;
}Démo
https://codepen.io/kentechgeek/pen/zyxqyxz
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
Vanfs peut tirer parti des balises HTML personnalisées fournies par les composants Web avec des systèmes de conception : Microsoft Fluent, Google Material Design, etc.
import {
provideFluentDesignSystem ,
fluentCard ,
fluentCheckbox
} from "@fluentui/web-components" ;
provideFluentDesignSystem ( )
. register (
fluentCard ( )
) ;
provideFluentDesignSystem ( )
. register (
fluentCheckbox ( )
) ; body {
font-family : sans-serif;
padding : 1 em ;
background-color : beige;
}
. custom {
--card-width : 200 px ;
--card-height : 150 px ;
padding : 22 px ;
}Program.fs module WebComponentsApp
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
let br : Tag = tags?br
// Define the fluent-card and fluent-checkbox tags
let fluentCard : Tag = tags? `` fluent-card ``
let fluentCheckbox : Tag = tags? `` fluent-checkbox ``
let List =
fun _ ->
fluentCard [
{| `` class `` = " custom " |}
// class is a reserved word in F#
// so we use backticks to escape it
fluentCheckbox [ " Did you check this? " ]
br []
fluentCheckbox [{| `` checked `` = true ; disabled = true |}; " Is this disabled? " ]
br []
fluentCheckbox [{| `` checked `` = true |}; " Checked by default? " ]
]
add [ document.body ; List ()]
|> ignoreLorsque des modifications majeures sont apportées, le nettoyage du projet Fable est parfois nécessaire.
dotnet fable clean
dotnet fable watchnpx vite import '@material/web/textfield/filled-text-field.js' ;
import '@material/web/button/text-button.js' ;
import '@material/web/button/outlined-button.js' ; . custom3 {
--card-width : 460 px ;
--card-height : 150 px ;
padding : 20 px ;
}
. row {
align-items : flex-start;
display : flex;
flex-wrap : wrap;
gap : 16 px ;
}
. buttons {
justify-content : flex-end;
padding : 16 px ;
}
md-filled-text-field ,
md-outlined-text-field {
width : 200 px ;
} module MaterialUI
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
let div : Tag = tags?div
let form : Tag = tags?form
let fluentCard : Tag = tags? `` fluent-card ``
let mdFilledTextField : Tag = tags? `` md-filled-text-field ``
let mdTextButton : Tag = tags? `` md-text-button ``
let mdOutlinedButton : Tag = tags? `` md-outlined-button ``
let Form =
fun _ ->
fluentCard [
{| `` class `` = " custom3 " |}
form [
div [
{| `` class `` = " row " |}
mdFilledTextField [
{|
label = " First name "
name = " first-name "
required = " "
autocomplete = " given-name "
|}
]
mdFilledTextField [
{|
label = " Last name "
name = " last-name "
required = " "
autocomplete = " family-name "
|}
]
]
div [
{| `` class `` = " row buttons " |}
mdTextButton [
{| `` type `` = " reset " |}
" Reset "
]
mdOutlinedButton [
{| `` type `` = " submit " |}
" Submit "
]
]
]
]
add [ document.body ; Form ()]
|> ignorenpx vite buildDémo
https://codepen.io/kentechgeek/pen/kkylwgn?Editors=1111
import '@material/web/icon/icon.js' ;
import '@material/web/iconbutton/icon-button.js' ; https://m3.material.io/styles/icons/overview
export let cssURLs = [
"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200"
] ;| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
Vanfs est décrit comme
1: 1 liaisons de F # à Vanjs (un minuscule cadre d'interface utilisateur réactif sans réact / jsx) + webcomponents + micro FRP
ou
VanFS est un modèle de projet F # pour les liaisons directes individuelles de Vanjs
Les liaisons 1: 1 sont absolument vraies dans le cadre des fonctionnalités de base pour la composition des internes d'utondes, mais pas un cas pour sa gestion de l'État.
VanJs lie réactivement ses objets d'état aux éléments DOM correspondants. Cela signifie que lorsqu'un objet d'état se met à jour, l'élément DOM correspondant se met également à jour automatiquement. Cette approche est une caractéristique commune parmi les bibliothèques de l'interface utilisateur déclaratives telles que React, SolidJS, etc.
Ceci est la structure identique de:
Donc, c'est FRP.
La programmation réactive fonctionnelle (FRP) est un paradigme de programmation qui utilise des expressions mathématiques, en particulier des opérations binaires , comme moyen d'implémenter la programmation réactive .
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
Timeline est une bibliothèque FRP fondamentalement autonome, sans dépendances sur les fonctionnalités VanJS ou F # asynchrones. La base de code est une implémentation de fonction pure compacte d'environ 30 à 40 lignes de code.
Timeline<'a>record Timeline < 'a >
val mutable lastVal : 'a
val el : StateElement < 'a >| Champ | Description | Van. |
|---|---|---|
lastVal | Dernière valeur de la chronologie | State.val |
el | Élément DOM réactif de la chronologie | State |
Timeline<'a>Timeline'a -> Timeline < 'a > let counter = van . state ( 0 ) ;
console . log ( counter . val ) ;
// 0 let counter = Timeline 0
console.log counter.lastVal
// 0 Considérez la Timeline comme un conteneur spécifique pour une valeur, similaire à une cellule dans les applications de feuille de calcul.
let double = fun a -> a * 2
let timelineA = Timeline 1
let timelineB =
timelineA |> mapT double
console.log timelineB.lastVal
// 2Ce code pour l'opération binaire correspond simplement à l'utilisation de base des applications de feuille de calcul
Ceci est la structure identique de:
let double = a => a * 2 ;
let arrayA = [ 1 ] ;
let arrayB =
arrayA . map ( double ) ;
console . log ( arrayB ) ;
// [2] let double =
fun a -> a * 2
let listA = [ 1 ]
let listB =
listA |> List.map double
console.log listB
// [2] Nous pourrions reconnaître que le tableau [2] est identique à la cellule et à la valeur 2 d'une feuille de calcul; Cependant, la feuille de calcul et la chronologie maintiennent une double relation à mesure que les valeurs changent par rapport à la chronologie .
Timeline<'a> nextT'a -> Timeline < 'a > -> Timeline < 'a > let timelineA ' =
timelineA |> nextT 3 Ou, dans la plupart des cas, nous n'avons pas besoin d'un autre timelineA' et voulons le jeter, alors ignore simplement la valeur renvoyée.
let timelineA = Timeline 1
timelineA
|> nextT 3
|> ignore
console.log timelineA.lastVal
// 3 let double = fun a -> a * 2
// ① initialize timelineA
let timelineA = Timeline 1
// confirm the lastVal of timelineA
console.log timelineA.lastVal
// 1
// ② the binary operation
let timelineB =
timelineA |> mapT double
// confirm the lastVal of timelineB
console.log timelineB.lastVal
// 2
//=====================================
// ③ update the lastVal of timelineA
timelineA
|> nextT 3
|> ignore
// update to timelineA will trigger
// a reactive update of timelineB
// confirm the lastVal of timelineA & timelineB
console.log timelineA.lastVal
// 3
console.log timelineB.lastVal
// 6 import van from "vanjs-core"
const { button , div , h2 } = van . tags
const Counter =
( ) => {
const counter = van . state ( 0 )
van . derive ( ( ) =>
console . log ( `Counter: ${ counter . val } ` ) )
return div (
h2 ( "❤️ " , counter ) ,
button (
{
onclick : ( ) => ++ counter . val
} ,
"?"
) ,
button (
{
onclick : ( ) => -- counter . val
} ,
"?"
) ,
)
}
van . add ( document . body , Counter ( ) ) module CounterApp
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
open Van. TimelineElement // import Timeline
let div : Tag = tags?div
let h2 : Tag = tags?h2
let icon : Tag = tags? `` md-icon ``
let iconButton : Tag = tags? `` md-icon-button ``
let Counter =
fun _ ->
let counter = Timeline 0 // ① initialize an Timeline
counter // ② the binary operation of the Timeline
|> mapT ( fun value ->
console.log $ " Counter: {value} " )
|> ignore
// ignore the return value of `console.log`
div [
h2 [ " ❤️ " ; counter.el ] // ? `counter.el`
iconButton [ // for Reactive DOM element
{| onclick = fun _ ->
counter // ③ update the Timeline
|> nextT ( counter.lastVal + 1 )
|}
icon [ " thumb_up " ]
]
iconButton [
{| onclick = fun _ ->
counter // ③ update the Timeline
|> nextT ( counter.lastVal - 1 )
|}
icon [ " thumb_down " ]
]
]
add [ document.body ; Counter ()]
|> ignoreDémo
https://codepen.io/kentechgeek/pen/goyqnqb?Editors=1111
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
Compte tenu de la signification critique de NULL dans le développement de logiciels modernes, j'ai consacré un article distinct pour explorer ses concepts et avantages clés.
Types de valeur nullables dans F #
Un type de valeur nulle
Nullable<'T>représente tout type de structure qui pourrait également êtrenull. Cela est utile lors de l'interaction avec les bibliothèques et les composants qui peuvent choisir de représenter ces types de types, comme les entiers, avec une valeurnullpour des raisons d'efficacité. Le type sous-jacent qui soutient cette construction est System.Nullable.
peut ne représente que le type struct , quelle limitation est problématique.
En utilisant des types de référence nullables dans F #
F #: Comment convertir l'option <'A> en nullable, aussi quand «A peut être System.String?
Ce serait bien si nous pouvions écrire des types nullables, y compris les types de référence dans F #.
F # RFC FS-1060 - Types de référence nullables
let nullable1 =
Null
let nullable2 =
NullableT " hello "
log nullable1
// Null
log nullable2
// T hello
log nullable2.Value
// hello Cette spécification ressemble à des types de valeurs nullables natifs de F #, mais contrairement à celui-ci, NullableT peut également représenter les types de référence.
F # Le support de nullness pourrait venir bientôt!
Un aperçu des travaux effectués sur le compilateur F # pour prendre en charge les capacités de null de .NET.
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
En utilisant le type nullable , nous pouvons fournir de nouveaux opérateurs qui s'associent à la chronologie .
Initialisation d'une chronologie avec une valeur Null , la fonction fournie reste non exécutée et attend dans un état en attente. Une fois que la valeur de chronologie est mise à jour vers une valeur non Null par un événement valide, la fonction est ensuite déclenchée et exécutée.
Timeline<NullableT<'a>>TimelineNullableT < 'a > -> Timeline < NullableT < 'a >> let timelineNullable = Timeline Null
log timelineNullable.lastVal // use `log` of Timeline
// NullConsidérez cette chronologie comme une cellule vide dans les applications de feuille de calcul.
Type de Timeline et fonction:
① Fonction pour initialiser Timeline<'a>
① Fonction pour initialiser Timeline<NullableT<'a>>
est la même entité .
Considérer Timeline peut accepter les types génériques de 'a incluant NullableT<'a> .
D'un autre côté, dans le cas de Timeline<NullableT<'a>> où la valeur du paramètre est un type nullable, si nous avons besoin du comportement Timeline pour ignorer la fonction fournie et passer simplement la valeur Null lorsque le paramètre est Null , nous pouvons utiliser des opérateurs spécifiques comme indiqué ci-dessous.
mapTN ( NullableT < 'a > -> NullableT < 'b >) -> ( Timeline < NullableT < 'a >> -> Timeline < NullableT < 'b >>)bindTN ( NullableT < 'a > -> Timeline < NullableT < 'b >>) -> ( Timeline < NullableT < 'a >> -> Timeline < NullableT < 'b >>) Lorsque l'opérateur binaire: mapT ,
let double =
fun a -> NullableT ( a * 2 )
// ① initialize timelineA
let timelineA = Timeline Null
log timelineA.lastVal // use `log` of Timeline
// Null
// ② the binary operation
let timelineB =
timelineA |> mapTN double
// currently, `timelineA = Timeline Null`
// so, `double` function is ignored
// and `timelineB` value becomes `Null`
log timelineB.lastVal // use `log` of Timeline
// NullCe code pour l'opération binaire correspond simplement à l'utilisation de base des applications de feuille de calcul.
let timelineA ' =
timelineA |> nextTN ( NullableT 3 ) Ou, dans la plupart des cas, nous n'avons pas besoin d'un autre timelineA' et voulons le jeter, alors ignore simplement la valeur renvoyée.
Timeline<'a> let double =
fun a -> NullableT ( a * 2 )
// ① initialize timelineA
let timelineA = Timeline Null
log timelineA.lastVal // use `log` of Timeline
// Null
// ② the binary operation
let timelineB =
timelineA |> mapTN double
// currently, `timelineA = Timeline Null`
// so, `double` function is ignored
// and `timelineB` value becomes `Null`
log timelineB.lastVal // use `log` of Timeline
// Null
// ③ update the lastVal of timelineA
timelineA
|> nextTN ( NullableT 3 )
|> ignore
log timelineA.lastVal // use `log` of Timeline
// T 3
// Now, `timelineA` value is updated to non `Null` value
// Accordingly, `timelineB` reactively becomes `double` of it
log timelineB.lastVal
// T 6 module Number
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
let h4 : Tag = tags?h4
let fluentCard : Tag = tags? `` fluent-card ``
let fluentTextField : Tag = tags? `` fluent-text-field ``
let Number =
fun _ ->
let number = Timeline Null
let numberX2 =
number
|> mapTN ( fun n -> NullableT ( n * 2 )) //System.Nullable
fluentCard [
{| `` class `` = " custom1 " |}
h4 [ " Number " ]
fluentTextField [
{|
appearance = " outline "
required = true
`` type `` = " number "
placeholder = " 1 "
oninput =
fun e ->
let value =
if e?target?value = " "
then Null
else NullableT e?target?value
if value = Null // clear the output textField
then numberX2
|> nextTN Null
|> ignore
document.getElementById ( " output-field " )? value
<- " Null " // clear the output textField
else ()
number
|> nextTN value
|> ignore
|}
]
h4 [ " Number × 2 " ]
fluentTextField [
{|
appearance = " outline "
readonly = true
value = numberX2.el
id = " output-field "
|}
]
]
add [ document.body ; Number ()]
|> ignoreDémo
https://codepen.io/kentechgeek/pen/wvznvzj?editors=1111
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
Bien que les opérateurs de chronologie nullables offrent un principe de base similaire à la promesse de JavaScript, ils ne sont pas capables de gérer le chaînage des tâches, comme Promie.Ensuivre.
Sur la base de la chronologie nullable , nous pouvons obtenir une tâche de chronologie qui est capable de chaîner des tâches.
TaskTimeline < NullableT < 'a >> -> 'b -> unit let task =
fun timelineResult previousResult ->
log " -----------task1 started... "
log previousResult
// delay-------------------------------
let f = fun _ ->
log " .......task1 done "
timelineResult
|> nextTN ( NullableT 1 )
|> ignore
setTimeout f 2000taskTTask < 'a , NullableT < 'a0 >> -> Timeline < NullableT < 'a >> -> Timeline < NullableT < 'a >> let timelineStarter =
Timeline ( NullableT 0 )
// tasks start immediately
timelineStarter
|> taskT task1
|> taskT task2
|> taskT task3
|> ignore| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
taskConcat ou (+>) ( Task -> Task ) -> Task let task12 =
task1 +> task2
let task123 =
task1 +> task2 +> task3
let task1234 =
task123 +> task4 module Tasks
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskConcat
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let br : Tag = tags? `` br ``
let fluentCard : Tag = tags? `` fluent-card ``
let linerProgress : Tag = tags? `` md-linear-progress ``
let Tasks =
fun _ ->
let progressInit = false
let progressStart = true
let progressDone = false
let percentInit = 0.0
let percentStart = 0.0
let percentDone = 1.0
let timelineProgress1 = Timeline progressInit
let timelineProgress2 = Timeline progressInit
let timelineProgress3 = Timeline progressInit
let timelinePercent1 = Timeline percentInit
let timelinePercent2 = Timeline percentInit
let timelinePercent3 = Timeline percentInit
let taskStart =
fun timelineProgress timelinePercent ->
timelineProgress
|> nextT progressStart
|> ignore
timelinePercent
|> nextT percentStart
|> ignore
let taskDone =
fun timelineProgress timelinePercent timelineResult ->
timelineProgress
|> nextT progressDone
|> ignore
timelinePercent
|> nextT percentDone
|> ignore
timelineResult
|> nextTN ( NullableT 999 )
|> ignore
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
taskStart timelineProgress1 timelinePercent1
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
taskDone timelineProgress1 timelinePercent1 timelineResult
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
taskStart timelineProgress2 timelinePercent2
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
taskDone timelineProgress2 timelinePercent2 timelineResult
setTimeout f 2500
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
taskStart timelineProgress3 timelinePercent3
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
taskDone timelineProgress3 timelinePercent3 timelineResult
setTimeout f 2500
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +>
task2 +>
task3
timelineStarter
|> taskT task123
|> ignore
(* task123 can be written as below
timelineStarter
|> taskT task1
|> taskT task2
|> taskT task3
|> ignore
*)
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN ( NullableT 0 )
|> ignore
setTimeout start 2000
fluentCard [
{| `` class `` = " custom2 " |}
br []
linerProgress [
{| indeterminate = timelineProgress1.el
value = timelinePercent1.el |}
]
br []
linerProgress [
{| indeterminate = timelineProgress2.el
value = timelinePercent2.el |}
]
br []
linerProgress [
{| indeterminate = timelineProgress3.el
value = timelinePercent3.el |}
]
]
add [ document.body ; Tasks ()]
|> ignoreDémo
https://codepen.io/kentechgeek/pen/jordjvy?Editors=1111
module Tasks
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskConcat
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let nonNull = NullableT true // some non-null value
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
timelineResult
|> nextTN nonNull
|> ignore
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
timelineResult
|> nextTN nonNull
|> ignore
setTimeout f 1000
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
timelineResult
|> nextTN nonNull
|> ignore
setTimeout f 3000
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +>
task2 +>
task3
timelineStarter
|> taskT task123
|> ignore
(* task123 can be written as below
timelineStarter
|> taskT task1
|> taskT task2
|> taskT task3
|> ignore
*)
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN nonNull
|> ignore
setTimeout start 2000
Démo
https://codepen.io/kentechgeek/pen/baeeyvl?editors=1111
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
taskOr ou (+|) ( Task -> Task ) -> Task let task12 =
task1 +| task2
let task123 =
task1 +| task2 +| task3
let task1234 =
task123 +| task4 module TaskOr
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskOr
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let nonNull = NullableT true
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
timelineResult
|> nextTN ( NullableT " task1 " )
|> ignore
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
timelineResult
|> nextTN ( NullableT " task2 " )
|> ignore
setTimeout f 1000
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
timelineResult
|> nextTN ( NullableT " task3 " )
|> ignore
setTimeout f 3000
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +| task2 +| task3
let taskOutput =
fun timelineResult ( previousResult : NullableT < string >)
-> log ( " The fastest result from: "
+ previousResult.Value )
timelineStarter
|> taskT task123 // Run all tasks then return the fastest result
|> taskT taskOutput // log the fastest result
|> ignore
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN nonNull
|> ignore
setTimeout start 2000
Démo
https://codepen.io/kentechgeek/pen/zyxqgwq?Editors=1111
| Contenu |
|---|
| ? Vanfs Polyvalence de la technologie Web pour le développement d'applications multiplateforme |
| Commencer |
| Composants Web |
| ⚡️ Programmation réactive fonctionnelle (FRP) Qu'est-ce que la programmation fonctionnelle? Comment le lecteur de code de programmation fonctionnelle? |
| ⏱️ Chronologie |
| ⏱️ types nullables Qu'est-ce que les types nuls, nullables et d'options? |
| ⏱️ chronologie nullable |
| ⏱️ Tâche de chronologie |
| ⏱️ Tâche de chronologie Concat |
| ⏱️ Tâche de chronologie ou |
| ⏱️ Tâche de chronologie et |
| Discussions |
taskAnd et (+&) ( Task -> Task ) -> Task let task12 =
task1 +& task2
let task123 =
task1 +& task2 +& task3
let task1234 =
task123 +& task4 module TaskAnd
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskAnd
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let nonNull = NullableT true
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
timelineResult
|> nextTN ( NullableT " task1 " )
|> ignore
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
timelineResult
|> nextTN ( NullableT " task2 " )
|> ignore
setTimeout f 1000
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
timelineResult
|> nextTN ( NullableT " task3 " )
|> ignore
setTimeout f 3000
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +& task2 +& task3
let taskOutput =
fun timelineResult ( previousResult : NullableT < ListResult < 'a >>)
-> log previousResult.Value.results
timelineStarter
|> taskT task123 // Run all tasks then return the list of results
|> taskT taskOutput // log the list of results
|> ignore
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN nonNull
|> ignore
setTimeout start 2000
Démo
https://codepen.io/kentechgeek/pen/pobmjzq?Editors=1111