KnockoutJS - Componenti

I componenti sono un modo enorme per organizzare il codice dell'interfaccia utente per strutturare un'applicazione di grandi dimensioni e promuovere la riusabilità del codice.

È ereditato o annidato da un altro componente. Per il caricamento e la configurazione, definisce le proprie convenzioni o logica.

È confezionato per essere riutilizzato in tutta l'applicazione o il progetto. Rappresenta le sezioni complete dell'applicazione o piccoli controlli / widget. Può essere caricato o precaricato su richiesta.

Registrazione dei componenti

I componenti possono registrarsi utilizzando ko.components.register()API. Aiuta a caricare e rappresentare i componenti in KO. Il nome del componente con la configurazione è previsto per la registrazione. La configurazione specifica come determinare viewModel e template.

Syntax

I componenti possono essere registrati come segue:

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • Il component-name può essere qualsiasi stringa non vuota.

  • viewModel è facoltativo e può accettare uno qualsiasi dei formati viewModel elencati nelle sezioni successive.

  • template è obbligatorio e può accettare qualsiasi formato di modello elencato nelle sezioni successive.

Indicare un ViewModel

La tabella seguente elenca i formati viewModel che possono essere utilizzati per registrare i componenti.

Sr.No. viewModel Form e descrizione
1

constructor function

Crea un oggetto viewModel separato per ogni componente. L'oggetto o la funzione viene utilizzato per eseguire il binding nella visualizzazione dei componenti.

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

shared object instance

L'istanza dell'oggetto viewModel è condivisa. La proprietà dell'istanza viene passata per utilizzare direttamente l'oggetto.

var sharedViewModelInstance = { ... };

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

createViewModel

Chiama una funzione che funge da factory e può essere utilizzata come modello di visualizzazione che può restituire un oggetto.

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

AMD module

È un formato di modulo per definire i moduli in cui il modulo e le dipendenze vengono caricati entrambi in modo asincrono.

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

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

   return MyViewModel;
});

Dichiarare un modello

La tabella seguente elenca i formati del modello che possono essere utilizzati per registrare i componenti.

Sr.No. Moduli modello
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: ...
});

Componenti registrati come un singolo modulo AMD

Il modulo AMD può registrare un componente da solo senza utilizzare la coppia viewModel / template.

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

Associazione dei componenti

Esistono due modi per associare i componenti.

  • Full syntax- Passa il parametro e l'oggetto al componente. Può passare utilizzando le seguenti proprietà.

    • name - Aggiunge il nome del componente.

    • params - Può passare più parametri in oggetto sul componente.

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax - Passa la stringa come nome di un componente e non include parametri in essa.

<div data-bind = 'component: "component name"'></div>
  • Template-only components - I componenti possono definire solo il modello senza specificare il viewModel.

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element- I componenti possono essere utilizzati senza utilizzare un elemento contenitore aggiuntivo. Questo può essere fatto usandocontainerless flow controllo che è simile al tag di commento.

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

Elemento personalizzato

L'elemento personalizzato è un modo per eseguire il rendering di un componente. Qui puoi scrivere direttamente un nome di elemento di markup autodescrittivo invece di definire un segnaposto, dove i componenti sono legati attraverso di esso.

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

Parametro di passaggio

paramsl'attributo viene utilizzato per passare il parametro al componente viewModel. È simile all'attributo data-bind. Il contenuto dell'attributo params viene interpretato come un oggetto letterale JavaScript (proprio come un attributo data-bind), quindi puoi passare valori arbitrari di qualsiasi tipo. Può passare il parametro nei seguenti modi:

  • Communication between parent and child components- Il componente non è istanziato da solo, quindi le proprietà viewmodel sono riferite dall'esterno del componente e quindi sarebbero ricevute dal componente figlio viewmodel. Ad esempio, puoi vedere nella seguente sintassi thatModelValue è il viewmodel padre, che viene ricevuto dal costruttore viewModel figlio ModelProperty.

  • Passing observable expressions - Ha tre valori nel parametro params.

    • simpleExpression- È un valore numerico. Non coinvolge nessun osservabile.

    • simpleObservable- È un'istanza definita su viewModel padre. Il genitore viewModel otterrà automaticamente le modifiche sull'osservabile fatto dal figlio viewModel.

    • observableExpression- L'espressione legge l'osservabile quando l'espressione viene valutata da sola. Quando il valore osservabile cambia, anche il risultato dell'espressione può cambiare nel tempo.

Possiamo passare i parametri come segue:

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

Possiamo passare i parametri in viewModel come segue:

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

Passaggio del markup ai componenti

Il markup ricevuto viene utilizzato per creare un componente ed è selezionato come parte dell'output. I seguenti nodi vengono passati come parte dell'output nel modello del componente.

template: { nodes: $componentTemplateNodes }

Controllo dei nomi dei tag degli elementi personalizzati

I nomi che si registrano nei componenti utilizzando ko.components.register, lo stesso nome corrisponde ai nomi dei tag dell'elemento personalizzato. Possiamo cambiare i nomi dei tag degli elementi personalizzati sovrascrivendoli per controllare usandogetComponentNameForNode.

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

Registrazione di elementi personalizzati

Gli elementi personalizzati possono essere resi disponibili immediatamente, se viene utilizzato il caricatore di componenti predefinito e quindi il componente viene registrato utilizzando ko.components.register. Se non stiamo usando ilko.components.registere implementando il caricatore di componenti personalizzati, l'elemento personalizzato può essere utilizzato definendo qualsiasi nome di elemento scelto. Non è necessario specificare la configurazione quando si utilizzako.components.register poiché il caricatore di componenti personalizzati non lo utilizza più.

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

Eseguiamo i seguenti passaggi per vedere come funziona il codice sopra:

  • Salva il codice sopra in formato component_register.htm file.

  • Apri questo file HTML in un browser.

Caricatori di componenti

I caricatori di componenti vengono utilizzati per trasmettere la coppia template / viewModel in modo asincrono per il nome del componente specificato.

Il caricatore di componenti predefinito

Il caricatore di componenti predefinito dipende dalla configurazione registrata in modo esplicito. Ogni componente viene registrato prima di utilizzare il componente.

ko.components.defaultLoader

Funzioni di utilità del caricatore di componenti

Il caricatore di componenti predefinito può leggere e scrivere utilizzando le seguenti funzioni.

Sr.No. Funzioni di utilità e descrizione
1

ko.components.register(name, configuration)

Il componente è registrato.

2

ko.components.isRegistered(name)

Se il nome del componente particolare è già registrato, restituisce true altrimenti false.

3

ko.components.unregister(name)

Il nome del componente viene rimosso dal registro.

4

ko.components.get(name, callback)

Questa funzione passa a turno a ciascun caricatore registrato per trovare chi ha passato per primo la definizione viewModel / template per il nome del componente. Quindi restituisce la dichiarazione viewModel / template invocandocallback. Se il caricatore registrato non riesce a trovare nulla sul componente, allora invocacallback(null).

5

ko.components.clearCachedDefinition(name)

Questa funzione può essere chiamata quando vogliamo cancellare la data voce della cache del componente. Se il componente è necessario la prossima volta, verranno nuovamente consultati i caricatori.

Implementazione di un caricatore di componenti personalizzati

Il caricatore di componenti personalizzati può essere implementato nei seguenti modi:

  • getConfig(name, callback)- A seconda dei nomi, possiamo passare le configurazioni in modo programmatico. Possiamo chiamare callback (componentConfig) per passare le configurazioni, dove l'oggetto componentConfig può essere utilizzato da loadComponent o da qualsiasi altro caricatore.

  • loadComponent(name, componentConfig, callback)- Questa funzione risolve il viewModel e la parte del modello di configurazione a seconda del modo in cui è configurato. Possiamo chiamare callback (risultato) per passare la coppia viewmodel / template, dove il risultato dell'oggetto è definito dalle seguenti proprietà.

    • template- Obbligatorio. Restituisce la matrice di nodi DOM.

    • createViewModel(params, componentInfo)- Facoltativo. Restituisce l'oggetto viewModel a seconda di come è stata configurata la proprietà viewModel.

  • loadTemplate(name, templateConfig, callback)- I nodi DOM vengono passati in un modello utilizzando la logica personalizzata. L'oggetto templateConfig è una proprietà del modello da un oggetto componentConfig. callback (domNodeArray) viene chiamato per passare un array di nodi DOM.

  • loadViewModel(name, templateConfig, callback) - viewModel factory viene passato in una configurazione viewModel utilizzando una logica personalizzata.