KnockoutJS - 组件

组件是组织UI代码以构建大型应用程序和提高代码可重用性的一种巨大方式.

它是从其他组件继承或嵌套的.对于加载和配置,它定义了自己的约定或逻辑.

打包它以在整个应用程序或项目中重用.表示应用程序或小控件/小部件的完整部分.它可以按需加载或预加载.

组件注册

组件可以使用 ko.components.register() API.它有助于加载和表示KO中的组件.配置的组件名称需要注册.配置指定如何确定viewModel和模板.

语法

组件可以注册如下 :

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});


  • 组件名称可以是任何非空字符串.

  • viewModel 是可选的,可以采用下一节中列出的任何viewModel格式.

  • 模板是必需的,可以采用下一节中列出的任何模板格式.

说明ViewModel

下表列出了可用于注册组件的viewModel格式.

Sr.No.viewModel Forms&说明
1

构造函数

它为每个组件创建一个单独的viewModel对象.对象或函数用于在组件视图中绑定.

 
 function SomeComponentViewModel(params){
 this.someProperty = params.something ; 
} 
 ko.components.register('组件名称',{
 viewModel:SomeComponentViewModel,
模板:... 
});
2

共享对象实例

共享viewModel对象实例.传递实例属性以直接使用该对象.

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

createViewModel

它调用一个充当工厂的函数,可以用作可以返回对象的视图模型.

 ko.components.register('component name',{
 viewModel:{
 createViewModel:function(params,componentInfo){
 ...//功能代码
 ... 
} 
},
模板:.... 
});
4

AMD模块

这是一种模块格式,用于定义模块和依赖项都是异步加载的模块.

 ko.components.register('component name',{
 viewModel:{require:'some/module/name'},
 template:... 
}); 
 define(['knockout'],函数(ko){
函数MyViewModel(){
//... 
} 
返回MyViewModel; 
});

陈述模板

下表列出了可用于注册组件的模板格式.

Sr.No.模板表格
1

元素ID

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

元素实例

 
 var elemInstance = document.getElementById ("分量模板"); 
 ko.components.register('组件名称',{
模板:{element:elemInstance},
 viewModel:... 
});
3

标记字符串

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

DOM节点

 var emp = [
 document.getElementById('node 1'),
 document.getElementById('node 2'),
]; 
 ko.components.register('组件名称',{
模板:emp,
 viewModel:... 
});
5

文件fragement

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

AMD模块

 ko.components.register('组件名称',{
模板:{require:'some/template'},
 viewModel:... 
});

注册为单个AMD模块的组件

AMD模块可以自行注册一个组件而不使用viewModel/template对.

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


组件绑定

有两种组件绑定方式.

  • 完整语法 : 它将参数和对象传递给组件.它可以使用以下属性传递.

    • name : 它添加了组件名称.

    • params : 它可以在组件上的对象中传递多个参数.

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>


  • 速记语法 : 它将字符串作为组件名称传递,并且不包含参数.

<div data-bind ='component:"component name"'></div>


  • 仅模板组件 : 组件只能在不指定viewModel的情况下定义模板.

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});


  • 使用不带容器元素的组件 : 可以使用组件而无需使用额外的容器元件.这可以使用 containerless flow 控件完成,该控件类似于注释标记.

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


自定义元素

自定义元素是一种渲染组件的方式.在这里,您可以直接编写自描述标记元素名称,而不是定义占位符,其中组件通过它进行绑定.

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


传递参数

params 属性用于将参数传递给组件viewModel.它类似于data-bind属性. params属性的内容被解释为JavaScript对象文字(就像数据绑定属性一样),因此您可以传递任何类型的任意值.它可以通过以下方式传递参数 :

  • 父组件和子组件之间的通信 :  ;组件本身不是实例化的,因此viewmodel属性是从组件外部引用的,因此将由子组件视图模型接收.例如,您可以在以下语法中看到 ModelValue 是父视图模型,由子视图模型构造函数 ModelProperty 接收.

  • 传递可观察的表达式 : 它在params参数中有三个值.

    • simpleExpression : 这是一个数值.它不涉及任何可观察物.

    • simpleObservable : 它是在父viewModel上定义的实例.父viewModel将自动获取由子viewModel完成的observable的更改.

    • observableExpression : 当表达式由其自身评估时,表达式读取可观察量.当可观察值发生变化时,表达式的结果也会随着时间的推移而变化.

我们可以传递以下参数 :

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


我们可以在viewModel中传递参数,如下所示 :

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


将标记传递给组件

接收到的标记用于创建组件并被选为组件的一部分输出.以下节点作为组件模板中输出的一部分传递.

template: { nodes: $componentTemplateNodes }


控制自定义元素标记名称

使用 ko.components.register 在组件中注册的名称,同名对应于自定义元素标记名称.我们可以通过覆盖它来控制使用 getComponentNameForNode 来更改自定义元素标记名称.

 
 ko.components.getComponentNameForNode = function(node){
 ... 
 ...//功能代码
 ... 
}


注册自定义元素

如果使用默认的组件加载器,则可以立即使用自定义元素,因此使用 ko.components.register注册组件.如果我们不使用 ko.components.register 并实现自定义组件加载器,则可以通过定义任何选择的元素名称来使用自定义元素.当您使用 ko.components.register 时,无需指定配置,因为自定义组件加载器不再使用它.

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


示例

<!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>


输出

让我们执行以下步骤,了解上述代码的工作原理 :

  • 将上述代码保存在 component_register.htm 文件中.

  • 在浏览器中打开此HTML文件.

组件装载程序

组件加载器用于为给定的组件名称异步传递模板/viewModel对.

默认组件加载器

默认组件loader取决于显式注册的配置.在使用组件之前注册每个组件.

ko.components.defaultLoader


组件加载器实用程序函数

默认组件加载程序可以使用以下函数进行读写.

Sr.No.Utility功能&说明
1

ko.components.register(名称,配置)

组件已注册.

2

ko.components.isRegistered(name)

如果特定组件名称已经注册,则返回true,否则返回false.

3

ko.components.unregister(name)

组件名称已从注册表中删除.

4

ko.components.get(名称,回调)

此功能轮流转到每个已注册的加载程序,以查找谁通过组件名称的viewModel/template定义为第一个.然后它通过调用回调返回viewModel/template声明.如果注册的加载器找不到有关该组件的任何信息,那么它将调用回调(null).

5

ko.components.clearCachedDefinition(name)

当我们想要清除给定的组件缓存条目时,可以调用此函数.如果下次需要该组件,将再次咨询装载机.

实现自定义组件加载器

自定义组件加载器可以通过以下方式实现 :

  • getConfig(名称,回调) : 根据名称,我们可以以编程方式传递配置.我们可以调用callback(componentConfig)来传递配置,其中对象componentConfig可以被loadComponent或任何其他加载器使用.

  • loadComponent( name,componentConfig,callback) : 此函数根据配置的方式解析viewModel和config的模板部分.我们可以调用callback(result)来传递viewmodel/template对,其中对象结果由以下属性定义.

    • 模板 : 需要.返回DOM节点数组.

    • createViewModel(params,componentInfo) : 可选的.返回viewModel对象,具体取决于viewModel属性的配置方式.

  • loadTemplate(name,templateConfig,callback) :  DOM节点使用自定义逻辑在模板中传递.对象templateConfig是来自对象componentConfig的模板的属性.调用callback(domNodeArray)来传递DOM节点数组.

  • loadViewModel(name,templateConfig,callback) :  viewModel工厂使用自定义逻辑在viewModel配置中传递.