KnockoutJS - Composants

Les composants sont un moyen énorme d'organiser le code de l'interface utilisateur pour structurer une grande application et promouvoir la réutilisabilité du code.

Il est hérité ou imbriqué d'un autre composant. Pour le chargement et la configuration, il définit ses propres conventions ou logique.

Il est packagé pour être réutilisé tout au long de l'application ou du projet. Représente les sections complètes de l'application ou les petits contrôles / widgets. Il peut être chargé ou préchargé à la demande.

Enregistrement des composants

Les composants peuvent s'enregistrer à l'aide du ko.components.register()API. Cela aide à charger et à représenter les composants dans KO. Le nom du composant avec la configuration est attendu pour l'enregistrement. La configuration spécifie comment déterminer le viewModel et le modèle.

Syntax

Les composants peuvent être enregistrés comme suit -

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • le component-name peut être n'importe quelle chaîne non vide.

  • viewModel est facultatif et peut prendre n'importe lequel des formats viewModel répertoriés dans les sections suivantes.

  • template est requis et peut prendre n'importe quel format de modèle répertorié dans les sections suivantes.

Indiquer un ViewModel

Le tableau suivant répertorie les formats viewModel qui peuvent être utilisés pour enregistrer les composants.

N ° Sr. viewModèle Formulaires et description
1

constructor function

Il crée un objet viewModel distinct pour chaque composant. L'objet ou la fonction est utilisé pour la liaison dans la vue des composants.

function SomeComponentViewModel(params) {
   this.someProperty = params.something;
}
ko.components.register('component name', {
   viewModel: SomeComponentViewModel,
   template: ...
});
2

shared object instance

L'instance d'objet viewModel est partagée. La propriété instance est transmise pour utiliser l'objet directement.

var sharedViewModelInstance = { ... };

ko.components.register('component name', {
   viewModel: { instance: sharedViewModelInstance },
   template: ...
});
3

createViewModel

Il appelle une fonction qui agit comme une fabrique et peut être utilisée comme modèle de vue pouvant renvoyer un objet.

ko.components.register('component name', {  
   viewModel: {  
      createViewModel: function (params, componentInfo) {  
         ...       //function code  
         ...
      }  
   },  
   template: ....  
});
4

AMD module

Il s'agit d'un format de module pour définir des modules où le module et les dépendances sont tous deux chargés de manière asynchrone.

ko.components.register('component name', {
   viewModel: { require: 'some/module/name' },
   template: ...
});

define(['knockout'], function(ko) {
   function MyViewModel() {
      // ...
   }

   return MyViewModel;
});

Énoncer un modèle

Le tableau suivant répertorie les formats de modèle qui peuvent être utilisés pour enregistrer les composants.

N ° Sr. Formulaires modèles
1

element ID

ko.components.register('component name', {
   template: { element: 'component-template' },
   viewModel: ...
});
2

element instance

var elemInstance = document.getElementById('component-template');

ko.components.register('component name', {
   template: { element: elemInstance },
   viewModel: ...
});
3

string of markup

ko.components.register('component name', {
   template: '<input data-bind = "value: yourName" />\
      <button data-bind = "click: addEmp">Add Emp </button>',
   viewModel: ...
});
4

DOM nodes

var emp = [
   document.getElementById('node 1'),
   document.getElementById('node 2'),
];

ko.components.register('component name', {
   template: emp,
   viewModel: ...
});
5

document fragement

ko.components.register('component name', {
   template: someDocumentFragmentInstance,
   viewModel: ...
});
6

AMD module

ko.components.register('component name', {
   template: { require: 'some/template' },
   viewModel: ...
});

Composants enregistrés en tant que module AMD unique

Le module AMD peut enregistrer un composant par lui-même sans utiliser la paire viewModel / template.

ko.components.register('component name',{ require: 'some/module'});

Liaison de composants

Il existe deux méthodes de liaison de composants.

  • Full syntax- Il transmet le paramètre et l'objet au composant. Il peut passer en utilisant les propriétés suivantes.

    • name - Il ajoute le nom du composant.

    • params - Il peut passer plusieurs paramètres en objet sur le composant.

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax - Il transmet la chaîne en tant que nom de composant et n'inclut pas de paramètre.

<div data-bind = 'component: "component name"'></div>
  • Template-only components - Les composants peuvent uniquement définir un modèle sans spécifier le viewModel.

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element- Les composants peuvent être utilisés sans utiliser d'élément de conteneur supplémentaire. Cela peut être fait en utilisantcontainerless flow contrôle qui est similaire à la balise de commentaire.

<!--ko.component: ""-->
<!--/ko-->

Élément personnalisé

L'élément personnalisé est un moyen de rendre un composant. Ici, vous pouvez écrire directement un nom d'élément de balisage auto-descriptif au lieu de définir un espace réservé, dans lequel les composants sont liés.

<products-list params = "name: userName, type: userType"></products-list>

Paramètre de passage

paramsL'attribut est utilisé pour transmettre le paramètre au composant viewModel. Il est similaire à l'attribut data-bind. Le contenu de l'attribut params est interprété comme un littéral d'objet JavaScript (tout comme un attribut de liaison de données), vous pouvez donc transmettre des valeurs arbitraires de tout type. Il peut transmettre le paramètre de la manière suivante -

  • Communication between parent and child components- Le composant n'est pas instancié par lui-même, de sorte que les propriétés de viewmodel sont référencées de l'extérieur du composant et seraient donc reçues par le composant enfant viewmodel. Par exemple, vous pouvez voir dans la syntaxe suivante queModelValue est le viewmodel parent, qui est reçu par le constructeur viewModel enfant ModelProperty.

  • Passing observable expressions - Il a trois valeurs dans le paramètre params.

    • simpleExpression- C'est une valeur numérique. Il n'implique aucun observable.

    • simpleObservable- Il s'agit d'une instance définie sur le viewModel parent. Le viewModel parent obtiendra automatiquement les modifications sur l'observable effectuées par le viewModel enfant.

    • observableExpression- Expression lit l'observable lorsque l'expression est évaluée par elle-même. Lorsque la valeur observable change, le résultat de l'expression peut également changer avec le temps.

Nous pouvons passer les paramètres comme suit -

<some-component
   params = 'simpleExpression: 1 + 1,
      simpleObservable: myObservable,
      observableExpression: myObservable() + 1'>
</some-component>

Nous pouvons passer les paramètres dans viewModel comme suit -

<some-component
   params = 'objectValue:{a: 3, b: 2},
      dateValue: new date(),
      stringValue: "Hi",
      numericValue:123,
      boolValue: true/false,
      ModelProperty: ModelValue'>
</some-component>

Passage du balisage aux composants

Le balisage reçu est utilisé pour créer un composant et est sélectionné comme partie de la sortie. Les nœuds suivants sont transmis dans le cadre de la sortie dans le modèle de composant.

template: { nodes: $componentTemplateNodes }

Contrôle des noms de balises d'élément personnalisé

Les noms que vous enregistrez dans les composants en utilisant ko.components.register, le même nom correspond aux noms de balises d'élément personnalisé. Nous pouvons modifier les noms de balises d'élément personnalisé en le remplaçant pour contrôler à l'aide degetComponentNameForNode.

ko.components.getComponentNameForNode = function(node) {
   ...
   ...   //function code
   ...
}

Enregistrement d'éléments personnalisés

Les éléments personnalisés peuvent être rendus disponibles immédiatement, si le chargeur de composant par défaut est utilisé et donc le composant est enregistré en utilisant ko.components.register. Si nous n'utilisons pas leko.components.registeret implémenter le chargeur de composants personnalisés, alors l'élément personnalisé peut être utilisé en définissant n'importe quel nom d'élément de votre choix. Il n'est pas nécessaire de spécifier la configuration lorsque vous utilisezko.components.register car le chargeur de composants personnalisés ne l'utilise plus.

ko.components.register('custom-element', { ......... });

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Components</title>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
   </head>
   
   <body>
      <!--params attribute is used to pass the parameter to component viewModel.-->
      <click params = "a: a, b: b"></click>

      <!--template is used for a component by specifying its ID -->
      <template id = "click-l">
         <div data-bind = "text: a"></div>

         <!--Use data-bind attribute to bind click:function() to ViewModel. -->
         <button data-bind = "click:function(){callback(1)}">Increase</button>
         <button data-bind = "click:function(){callback(-1)}">Decrease</button>
      </template>

      <script>
         //Here components are registered
         ko.components.register('click', {
            
            viewModel: function(params) {
               self = this;
               this.a = params.a;
               this.b = params.b;

               this.callback = function(num) {
                  self.b(parseInt(num));
                  self.a( self.a() + parseInt(num) );
               };
            },
            template: { element: 'click-l' }
         });

         //keeps an eye on variable for any modification in data
         function viewModel() {
            this.a = ko.observable(2);
            this.b = ko.observable(0);
         }

         ko.applyBindings(new viewModel() );
      </script>
      
   </body>
</html>

Output

Exécutons les étapes suivantes pour voir comment fonctionne le code ci-dessus -

  • Enregistrez le code ci-dessus dans component_register.htm fichier.

  • Ouvrez ce fichier HTML dans un navigateur.

Chargeurs de composants

Les chargeurs de composants sont utilisés pour transmettre la paire modèle / viewModel de manière asynchrone pour le nom de composant donné.

Le chargeur de composants par défaut

Le chargeur de composants par défaut dépend de la configuration explicitement enregistrée. Chaque composant est enregistré avant d'utiliser le composant.

ko.components.defaultLoader

Fonctions de l'utilitaire Component Loader

Le chargeur de composants par défaut peut lire et écrire à l'aide des fonctions suivantes.

N ° Sr. Fonctions utilitaires et description
1

ko.components.register(name, configuration)

Le composant est enregistré.

2

ko.components.isRegistered(name)

Si le nom du composant particulier est déjà enregistré, alors il retourne comme vrai sinon faux.

3

ko.components.unregister(name)

Le nom du composant est supprimé du registre.

4

ko.components.get(name, callback)

Cette fonction va tour à tour à chaque chargeur enregistré pour trouver qui a passé la définition viewModel / template pour le nom du composant en premier. Ensuite, il renvoie la déclaration viewModel / template en invoquantcallback. Si le chargeur enregistré n'a rien trouvé sur le composant, il appellecallback(null).

5

ko.components.clearCachedDefinition(name)

Cette fonction peut être appelée lorsque nous voulons effacer l'entrée de cache de composant donnée. Si le composant est nécessaire la prochaine fois, les chargeurs seront à nouveau consultés.

Implémentation d'un chargeur de composants personnalisé

Le chargeur de composants personnalisés peut être implémenté des manières suivantes -

  • getConfig(name, callback)- En fonction des noms, on peut passer des configurations par programmation. Nous pouvons appeler callback (componentConfig) pour passer les configurations, où l'objet componentConfig peut être utilisé par le loadComponent ou tout autre chargeur.

  • loadComponent(name, componentConfig, callback)- Cette fonction résout le viewModel et la partie modèle de config en fonction de la façon dont il est configuré. Nous pouvons appeler callback (result) pour transmettre la paire viewmodel / template, où le résultat de l'objet est défini par les propriétés suivantes.

    • template- Obligatoire. Renvoie un tableau de nœuds DOM.

    • createViewModel(params, componentInfo)- Facultatif. Renvoie l'objet viewModel en fonction de la configuration de la propriété viewModel.

  • loadTemplate(name, templateConfig, callback)- Les nœuds DOM sont transmis dans un modèle à l'aide d'une logique personnalisée. L'objet templateConfig est une propriété du template d'un objet componentConfig. callback (domNodeArray) est appelé pour transmettre un tableau de nœuds DOM.

  • loadViewModel(name, templateConfig, callback) - La fabrique viewModel est passée dans une configuration viewModel à l'aide d'une logique personnalisée.