KnockoutJS - Componentes

Os componentes são uma ótima maneira de organizar o código da IU para estruturar um grande aplicativo e promover a reutilização do código.

Ele é herdado ou aninhado de outro componente. Para carregamento e configuração, ele define suas próprias convenções ou lógica.

Ele é empacotado para ser reutilizado em todo o aplicativo ou projeto. Representa as seções completas do aplicativo ou pequenos controles / widgets. Ele pode ser carregado ou pré-carregado sob demanda.

Registro de Componente

Os componentes podem se registrar usando o ko.components.register()API. Ajuda a carregar e representar os componentes em KO. O nome do componente com configuração é esperado para registro. A configuração especifica como determinar o viewModel e o modelo.

Syntax

Os componentes podem ser registrados da seguinte forma -

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • o component-name pode ser qualquer string não vazia.

  • viewModel é opcional e pode assumir qualquer um dos formatos de viewModel listados nas próximas seções.

  • template é obrigatório e pode assumir qualquer um dos formatos de modelo listados nas próximas seções.

Declarando um ViewModel

A tabela a seguir lista os formatos de viewModel que podem ser usados ​​para registrar os componentes.

Sr. Não. Formulários e descrição de viewModel
1

constructor function

Ele cria um objeto viewModel separado para cada componente. O objeto ou função é usado para vincular na visualização de componentes.

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

shared object instance

A instância do objeto viewModel é compartilhada. A propriedade da instância é passada para usar o objeto diretamente.

var sharedViewModelInstance = { ... };

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

createViewModel

Ele chama uma função que atua como uma fábrica e pode ser usada como modelo de visualização que pode retornar um objeto.

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

AMD module

É um formato de módulo para definir módulos em que o módulo e as dependências são carregados de forma assíncrona.

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

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

   return MyViewModel;
});

Declarando um modelo

A tabela a seguir lista os formatos de modelo que podem ser usados ​​para registrar os componentes.

Sr. Não. Formulários de modelo
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: ...
});

Componentes registrados como um único módulo AMD

O módulo AMD pode registrar um componente sozinho sem usar o par viewModel / template.

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

Vinculação de componente

Existem duas formas de vinculação de componentes.

  • Full syntax- Passa o parâmetro e o objeto para o componente. Ele pode passar usando as seguintes propriedades.

    • name - Adiciona o nome do componente.

    • params - Pode passar vários parâmetros em objeto no componente.

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax - Ele passa a string como um nome de componente e não inclui o parâmetro nele.

<div data-bind = 'component: "component name"'></div>
  • Template-only components - Os componentes só podem definir o modelo sem especificar o viewModel.

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element- Os componentes podem ser usados ​​sem o uso de elemento de contêiner extra. Isso pode ser feito usandocontainerless flow controle que é semelhante à tag de comentário.

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

Elemento Personalizado

O elemento personalizado é uma forma de renderizar um componente. Aqui, você pode escrever diretamente um nome de elemento de marcação auto-descritivo em vez de definir um espaço reservado, onde os componentes são vinculados a ele.

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

Parâmetro de passagem

paramsatributo é usado para passar o parâmetro para o componente viewModel. É semelhante ao atributo de ligação de dados. O conteúdo do atributo params é interpretado como um literal de objeto JavaScript (assim como um atributo data-bind), então você pode passar valores arbitrários de qualquer tipo. Ele pode passar o parâmetro das seguintes maneiras -

  • Communication between parent and child components- O componente não é instanciado por si mesmo, então as propriedades do viewmodel são referenciadas de fora do componente e, portanto, seriam recebidas pelo viewmodel do componente filho. Por exemplo, você pode ver na sintaxe a seguir queModelValue é o viewmodel pai, que é recebido pelo construtor viewModel filho ModelProperty.

  • Passing observable expressions - Possui três valores no parâmetro params.

    • simpleExpression- É um valor numérico. Não envolve quaisquer observáveis.

    • simpleObservable- É uma instância definida no viewModel pai. O viewModel pai obterá automaticamente as alterações no observável feitas pelo viewModel filho.

    • observableExpression- Expression lê o observável quando a expressão é avaliada por si mesma. Quando o valor observável muda, o resultado da expressão também pode mudar com o tempo.

Podemos passar os parâmetros da seguinte forma -

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

Podemos passar os parâmetros em viewModel da seguinte maneira -

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

Passando marcação para componentes

A marcação recebida é usada para criar um componente e é selecionada como parte da saída. Os seguintes nós são passados ​​como parte da saída no modelo de componente.

template: { nodes: $componentTemplateNodes }

Controle de nomes de tag de elemento personalizado

Os nomes que você registra nos componentes usando ko.components.register, o mesmo nome corresponde aos nomes de tag do elemento personalizado. Podemos alterar os nomes de tag do elemento personalizado, substituindo-o para controlar usandogetComponentNameForNode.

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

Registro de elementos personalizados

Os elementos personalizados podem ser disponibilizados imediatamente, se o carregador de componente padrão for usado e, portanto, o componente for registrado usando ko.components.register. Se não estivermos usando oko.components.registere implementar o carregador de componente personalizado, o elemento personalizado pode ser usado definindo qualquer nome de elemento de sua escolha. Não há necessidade de especificar a configuração quando você estiver usandoko.components.register já que o carregador de componente personalizado não o usa mais.

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

Vamos realizar as etapas a seguir para ver como o código acima funciona -

  • Salve o código acima em component_register.htm Arquivo.

  • Abra este arquivo HTML em um navegador.

Carregadores de componentes

Os carregadores de componente são usados ​​para passar o par template / viewModel de forma assíncrona para o nome de componente fornecido.

O carregador de componente padrão

O carregador de componente padrão depende da configuração registrada explicitamente. Cada componente é registrado antes de usar o componente.

ko.components.defaultLoader

Funções de utilitário do carregador de componentes

O carregador de componente padrão pode ler e gravar usando as seguintes funções.

Sr. Não. Funções utilitárias e descrição
1

ko.components.register(name, configuration)

O componente está registrado.

2

ko.components.isRegistered(name)

Se o nome do componente específico já estiver registrado, ele retornará como verdadeiro, caso contrário, será falso.

3

ko.components.unregister(name)

O nome do componente é removido do registro.

4

ko.components.get(name, callback)

Essa função vai passo a passo para cada carregador registrado para encontrar quem passou a definição de viewModel / template para o nome do componente como primeiro. Em seguida, ele retorna a declaração viewModel / template invocandocallback. Se o carregador registrado não puder encontrar nada sobre o componente, ele invocacallback(null).

5

ko.components.clearCachedDefinition(name)

Esta função pode ser chamada quando queremos limpar a entrada de cache de componente fornecida. Se o componente for necessário na próxima vez, novamente os carregadores serão consultados.

Implementando um carregador de componente personalizado

O carregador de componente personalizado pode ser implementado das seguintes maneiras -

  • getConfig(name, callback)- Dependendo dos nomes, podemos passar as configurações de forma programática. Podemos chamar o callback (componentConfig) para passar as configurações, onde o objeto componentConfig pode ser usado pelo loadComponent ou qualquer outro loader.

  • loadComponent(name, componentConfig, callback)- Esta função resolve o viewModel e a parte do template da configuração dependendo da forma como está configurado. Podemos chamar o callback (resultado) para passar o par viewmodel / template, onde o resultado do objeto é definido pelas seguintes propriedades.

    • template- Obrigatório. Retorna a matriz de nós DOM.

    • createViewModel(params, componentInfo)- Opcional. Retorna o objeto viewModel dependendo de como a propriedade viewModel foi configurada.

  • loadTemplate(name, templateConfig, callback)- Os nós DOM são passados ​​em um modelo usando lógica personalizada. O objeto templateConfig é uma propriedade do template de um objeto componentConfig. callback (domNodeArray) é chamado para passar uma matriz de nós DOM.

  • loadViewModel(name, templateConfig, callback) - a fábrica viewModel é passada em uma configuração viewModel usando lógica customizada.