KnockoutJS - ส่วนประกอบ

ส่วนประกอบเป็นวิธีการจัดการโค้ด UI ที่ดีเยี่ยมสำหรับการจัดโครงสร้างแอปพลิเคชันขนาดใหญ่และส่งเสริมการใช้งานโค้ดซ้ำ

ได้รับการถ่ายทอดหรือซ้อนจากส่วนประกอบอื่น ๆ สำหรับการโหลดและการกำหนดค่าจะกำหนดอนุสัญญาหรือตรรกะของตัวเอง

บรรจุเพื่อใช้ซ้ำตลอดทั้งแอปพลิเคชันหรือโครงการ แสดงถึงส่วนทั้งหมดของแอปพลิเคชันหรือส่วนควบคุม / วิดเจ็ตขนาดเล็ก สามารถโหลดหรือโหลดล่วงหน้าได้ตามต้องการ

การลงทะเบียนส่วนประกอบ

ส่วนประกอบสามารถลงทะเบียนโดยใช้ ko.components.register()API ช่วยในการโหลดและแสดงส่วนประกอบใน KO คาดว่าชื่อส่วนประกอบที่มีการกำหนดค่าสำหรับการลงทะเบียน คอนฟิกูเรชันระบุวิธีกำหนด viewModel และ template

Syntax

ส่วนประกอบสามารถลงทะเบียนได้ดังนี้ -

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • component-name สามารถเป็นสตริงที่ไม่ว่างเปล่าก็ได้

  • viewModel เป็นทางเลือกและสามารถใช้รูปแบบ viewModel ที่ระบุไว้ในส่วนถัดไป

  • template เป็นสิ่งจำเป็นและสามารถใช้รูปแบบเทมเพลตใดก็ได้ที่ระบุไว้ในส่วนถัดไป

การระบุ ViewModel

ตารางต่อไปนี้แสดงรูปแบบ viewModel ที่สามารถใช้เพื่อลงทะเบียนคอมโพเนนต์

ซีเนียร์ viewModel แบบฟอร์มและคำอธิบาย
1

constructor function

สร้างอ็อบเจ็กต์ viewModel แยกต่างหากสำหรับแต่ละคอมโพเนนต์ วัตถุหรือฟังก์ชันถูกใช้เพื่อผูกในมุมมองส่วนประกอบ

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

shared object instance

อินสแตนซ์อ็อบเจ็กต์ viewModel ถูกแชร์ คุณสมบัติอินสแตนซ์ถูกส่งผ่านไปใช้วัตถุโดยตรง

var sharedViewModelInstance = { ... };

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

createViewModel

เรียกใช้ฟังก์ชันที่ทำหน้าที่เป็นโรงงานและสามารถใช้เป็นโมเดลมุมมองที่สามารถส่งคืนวัตถุได้

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

AMD module

เป็นรูปแบบโมดูลสำหรับกำหนดโมดูลที่ทั้งโมดูลและการอ้างอิงถูกโหลดแบบอะซิงโครนัส

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

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

   return MyViewModel;
});

การระบุเทมเพลต

ตารางต่อไปนี้แสดงรูปแบบเทมเพลตที่สามารถใช้ในการลงทะเบียนส่วนประกอบ

ซีเนียร์ แบบฟอร์มเทมเพลต
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: ...
});

ส่วนประกอบที่ลงทะเบียนเป็นโมดูล AMD เดี่ยว

โมดูล AMD สามารถลงทะเบียนส่วนประกอบได้ด้วยตัวเองโดยไม่ต้องใช้คู่ viewModel / template

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

การผูกส่วนประกอบ

การผูกส่วนประกอบมีสองวิธี

  • Full syntax- ส่งผ่านพารามิเตอร์และวัตถุไปยังส่วนประกอบ สามารถส่งผ่านโดยใช้คุณสมบัติต่อไปนี้

    • name - เพิ่มชื่อส่วนประกอบ

    • params - สามารถส่งผ่านหลายพารามิเตอร์ในออบเจ็กต์บนคอมโพเนนต์

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax - ส่งผ่านสตริงเป็นชื่อส่วนประกอบและไม่รวมพารามิเตอร์ไว้ในนั้น

<div data-bind = 'component: "component name"'></div>
  • Template-only components - ส่วนประกอบสามารถกำหนดเทมเพลตได้โดยไม่ต้องระบุ viewModel

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element- ส่วนประกอบสามารถใช้ได้โดยไม่ต้องใช้องค์ประกอบคอนเทนเนอร์เพิ่มเติม ซึ่งสามารถทำได้โดยใช้containerless flow การควบคุมที่คล้ายกับแท็กความคิดเห็น

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

องค์ประกอบที่กำหนดเอง

องค์ประกอบที่กำหนดเองเป็นวิธีการแสดงผลองค์ประกอบ ที่นี่คุณสามารถเขียนชื่อองค์ประกอบมาร์กอัปแบบอธิบายตัวเองได้โดยตรงแทนที่จะกำหนดตัวยึดตำแหน่งโดยที่ส่วนประกอบต่างๆจะถูกผูกเข้าด้วยกัน

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

ผ่านพารามิเตอร์

paramsแอ็ตทริบิวต์ถูกใช้เพื่อส่งผ่านพารามิเตอร์ไปยัง component viewModel คล้ายกับแอตทริบิวต์การผูกข้อมูล เนื้อหาของแอตทริบิวต์ params ถูกตีความเหมือนตัวอักษรของวัตถุ JavaScript (เช่นเดียวกับแอตทริบิวต์การผูกข้อมูล) ดังนั้นคุณสามารถส่งผ่านค่าประเภทใดก็ได้โดยพลการ สามารถส่งผ่านพารามิเตอร์ด้วยวิธีต่อไปนี้ -

  • Communication between parent and child components- คอมโพเนนต์ไม่ได้สร้างอินสแตนซ์ด้วยตัวมันเองดังนั้นคุณสมบัติ viewmodel จึงถูกอ้างถึงจากภายนอกส่วนประกอบดังนั้นจึงจะได้รับโดย viewmodel องค์ประกอบลูก ตัวอย่างเช่นคุณสามารถดูไวยากรณ์ต่อไปนี้ว่าModelValue คือพาเรนต์วิวโมเดลซึ่งได้รับโดยคอนสตรัคเตอร์ viewModel ลูก ModelProperty.

  • Passing observable expressions - มีสามค่าในพารามิเตอร์ params

    • simpleExpression- เป็นค่าตัวเลข ไม่เกี่ยวข้องกับสิ่งที่สังเกตได้

    • simpleObservable- เป็นอินสแตนซ์ที่กำหนดไว้ในมุมมองแม่แบบ พาเรนต์ viewModel จะได้รับการเปลี่ยนแปลงที่สังเกตได้โดยอัตโนมัติที่ทำโดย child viewModel

    • 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) {
   ...
   ...   //function code
   ...
}

การลงทะเบียนองค์ประกอบที่กำหนดเอง

องค์ประกอบที่กำหนดเองสามารถทำให้พร้อมใช้งานได้ทันทีหากใช้ตัวโหลดส่วนประกอบเริ่มต้นและด้วยเหตุนี้ส่วนประกอบจึงถูกลงทะเบียนโดยใช้ ko.components.register. หากเราไม่ได้ใช้ไฟล์ko.components.registerและใช้ตัวโหลดคอมโพเนนต์ที่กำหนดเองจากนั้นสามารถใช้องค์ประกอบที่กำหนดเองได้โดยการกำหนดชื่อองค์ประกอบที่ต้องการ ไม่จำเป็นต้องระบุการกำหนดค่าเมื่อคุณใช้งานko.components.register เนื่องจากตัวโหลดส่วนประกอบแบบกำหนดเองไม่ได้ใช้งานอีกต่อไป

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

ลองทำตามขั้นตอนต่อไปนี้เพื่อดูว่าโค้ดด้านบนทำงานอย่างไร -

  • บันทึกรหัสด้านบนใน component_register.htm ไฟล์.

  • เปิดไฟล์ HTML นี้ในเบราว์เซอร์

รถตักชิ้นส่วน

ตัวโหลดคอมโพเนนต์ใช้เพื่อส่งผ่านคู่ template / viewModel แบบอะซิงโครนัสสำหรับชื่อส่วนประกอบที่กำหนด

ตัวโหลดส่วนประกอบเริ่มต้น

ตัวโหลดองค์ประกอบเริ่มต้นขึ้นอยู่กับการกำหนดค่าที่ลงทะเบียนไว้อย่างชัดเจน ส่วนประกอบแต่ละชิ้นได้รับการลงทะเบียนก่อนใช้ส่วนประกอบ

ko.components.defaultLoader

ฟังก์ชั่นยูทิลิตี้ Component Loader

ตัวโหลดคอมโพเนนต์เริ่มต้นสามารถอ่านและเขียนโดยใช้ฟังก์ชันต่อไปนี้

ซีเนียร์ ฟังก์ชั่นยูทิลิตี้และคำอธิบาย
1

ko.components.register(name, configuration)

ลงทะเบียนส่วนประกอบแล้ว

2

ko.components.isRegistered(name)

หากชื่อคอมโพเนนต์เฉพาะถูกลงทะเบียนแล้วจะส่งคืนเป็นจริงอื่นเท็จ

3

ko.components.unregister(name)

ชื่อคอมโพเนนต์จะถูกลบออกจากรีจิสทรี

4

ko.components.get(name, callback)

ฟังก์ชันนี้จะเปลี่ยนไปตามตัวโหลดที่ลงทะเบียนแต่ละตัวเพื่อค้นหาว่าใครส่งผ่านข้อกำหนด viewModel / template สำหรับชื่อคอมโพเนนต์เป็นอันดับแรก จากนั้นจะส่งคืนการประกาศ viewModel / template โดยการเรียกใช้callback. หากตัวโหลดที่ลงทะเบียนไม่พบสิ่งใดเกี่ยวกับส่วนประกอบนั้นจะเรียกใช้callback(null).

5

ko.components.clearCachedDefinition(name)

ฟังก์ชันนี้สามารถเรียกใช้ได้เมื่อเราต้องการล้างรายการแคชส่วนประกอบที่กำหนด หากต้องการส่วนประกอบในครั้งต่อไปจะมีการปรึกษารถตักอีกครั้ง

การใช้งานตัวโหลดส่วนประกอบที่กำหนดเอง

ตัวโหลดคอมโพเนนต์ที่กำหนดเองสามารถใช้งานได้ด้วยวิธีต่อไปนี้ -

  • getConfig(name, callback)- ขึ้นอยู่กับชื่อเราสามารถส่งผ่านการกำหนดค่าโดยทางโปรแกรมได้ เราสามารถโทรกลับ (componentConfig) เพื่อส่งผ่านคอนฟิกูเรชันโดยที่ loadComponent หรือ loader อื่น ๆ สามารถใช้ object componentConfig ได้

  • loadComponent(name, componentConfig, callback)- ฟังก์ชันนี้จะแก้ไข viewModel และส่วนแม่แบบของการกำหนดค่าขึ้นอยู่กับวิธีการกำหนดค่า เราสามารถโทรกลับ (ผลลัพธ์) เพื่อส่งผ่านคู่ viewmodel / template โดยที่ผลลัพธ์ของวัตถุถูกกำหนดโดยคุณสมบัติต่อไปนี้

    • template- จำเป็น ส่งคืนอาร์เรย์ของโหนด DOM

    • createViewModel(params, componentInfo)- ไม่บังคับ ส่งคืนวัตถุ viewModel ขึ้นอยู่กับว่าคุณสมบัติ viewModel ถูกกำหนดค่าอย่างไร

  • loadTemplate(name, templateConfig, callback)- โหนด DOM ถูกส่งผ่านในเทมเพลตโดยใช้ตรรกะที่กำหนดเอง อ็อบเจ็กต์ templateConfig เป็นคุณสมบัติของเทมเพลตจาก object componentConfig การเรียกกลับ (domNodeArray) ถูกเรียกเพื่อส่งผ่านอาร์เรย์ของโหนด DOM

  • loadViewModel(name, templateConfig, callback) - โรงงาน viewModel ถูกส่งผ่านในคอนฟิกูเรชัน viewModel โดยใช้ตรรกะที่กำหนดเอง