KnockoutJS - คู่มือฉบับย่อ

KnockoutJS เป็นไลบรารีที่เขียนด้วย JavaScript โดยใช้รูปแบบ MVVM ที่ช่วยให้นักพัฒนาสร้างเว็บไซต์ที่สมบูรณ์และตอบสนองได้ โมเดลจะแยกโมเดลของแอปพลิเคชัน (ข้อมูลที่เก็บไว้), มุมมอง (UI) และโมเดลมุมมอง (การเป็นตัวแทนของรูปแบบ JavaScript)

KnockoutJS ได้รับการพัฒนาและดูแลเป็นโครงการโอเพ่นซอร์สโดย Steve Sanderson พนักงานของ Microsoft เมื่อวันที่ 5 กรกฎาคม 2010 KO เป็นตัวย่อที่ใช้สำหรับ KnockoutJS KO รองรับเบราว์เซอร์กระแสหลักทั้งหมด - IE 6+, Firefox 3.5+, Chrome, Opera, Safari (เดสก์ท็อป / มือถือ)

คุณสมบัติของ KnockoutJS

นี่คือรายการคุณสมบัติที่โดดเด่นที่สุดของ KnockoutJS -

  • Declarative Binding- องค์ประกอบ HTML DOM เชื่อมต่อกับโมเดลผ่านแอตทริบิวต์การผูกข้อมูลโดยใช้ไวยากรณ์ที่เรียบง่ายมาก ทำให้การตอบสนองโดยใช้คุณสมบัตินี้ทำได้ง่าย

  • Automatic UI Refresh- การเปลี่ยนแปลงใด ๆ ที่ทำเพื่อดูข้อมูลโมเดลจะแสดงใน UI โดยอัตโนมัติและในทางกลับกัน ไม่จำเป็นต้องเขียนโค้ดเพิ่มเติม

  • Dependency Tracking- ความสัมพันธ์ระหว่างแอตทริบิวต์ KO และฟังก์ชัน / ส่วนประกอบของไลบรารี KO มีความโปร่งใส ติดตามการเปลี่ยนแปลงข้อมูลโดยอัตโนมัติในแอตทริบิวต์ KO และอัปเดตพื้นที่ที่ได้รับผลกระทบตามลำดับ

  • Templating - เทมเพลตเป็นวิธีที่ง่ายและสะดวกในการสร้างโครงสร้าง UI ที่ซับซ้อน - มีความเป็นไปได้ในการทำซ้ำหรือซ้อนบล็อก - เป็นฟังก์ชันของข้อมูลโมเดลมุมมอง

  • Extensible - ขยายพฤติกรรมที่กำหนดเองได้อย่างง่ายดาย

ทำไมต้องใช้ KnockoutJS?

  • ไลบรารี KnockoutJS มีวิธีที่ง่ายและสะอาดในการจัดการอินเทอร์เฟซที่ขับเคลื่อนด้วยข้อมูลที่ซับซ้อน หนึ่งสามารถสร้าง UI ที่อัปเดตด้วยตนเองสำหรับวัตถุ Javascript

  • เป็นไลบรารี JavaScript ที่บริสุทธิ์และใช้งานได้กับเว็บเฟรมเวิร์ก ไม่ใช่การแทนที่ JQuery แต่สามารถทำงานเป็นส่วนเสริมที่ให้คุณสมบัติอัจฉริยะได้

  • ไฟล์ไลบรารี KnockoutJS มีขนาดเล็กและน้ำหนักเบามาก

  • KnockoutJS เป็นอิสระจากกรอบงานอื่นใด เข้ากันได้กับเทคโนโลยีฝั่งไคลเอ็นต์หรือเซิร์ฟเวอร์อื่น ๆ

  • ที่สำคัญที่สุดของ KnockoutJS คือโอเพ่นซอร์สและใช้งานได้ฟรี

  • KnockoutJS มีเอกสารครบถ้วน เว็บไซต์อย่างเป็นทางการมีเอกสารประกอบฉบับเต็มรวมถึงเอกสาร API ตัวอย่างสดและบทแนะนำแบบโต้ตอบ

มันง่ายมากที่จะใช้ KnockoutJS เพียงอ้างอิงไฟล์ JavaScript โดยใช้แท็ก <script> ในหน้า HTML

Knockout.js สามารถเข้าถึงได้ด้วยวิธีต่อไปนี้ -

  • คุณสามารถดาวน์โหลดบิลด์การผลิตของ Knockout.js ได้จากเว็บไซต์ทางการ

    หน้าดังในภาพต่อไปนี้จะปรากฏขึ้น คลิกที่ลิงค์ดาวน์โหลดและคุณจะได้รับไฟล์ knockout.js ล่าสุด

ตอนนี้อ้างอิงไฟล์ดังที่แสดงในรหัสต่อไปนี้

<script type = 'text/javascript' src = 'knockout-3.3.0.js'></script>

อัปเดตแอตทริบิวต์ src เพื่อให้ตรงกับตำแหน่งที่เก็บไฟล์ที่ดาวน์โหลดไว้

  • คุณสามารถอ้างถึงไลบรารี KnockoutJS จาก CDNs -

    • คุณสามารถอ้างอิงไลบรารี KnockoutJS จากMicrosoft Ajax CDNในโค้ดของคุณดังนี้ -

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"></script>
  • หรือคุณสามารถอ้างถึงเวอร์ชันย่อของไลบรารี KnockoutJS จากCDNJSดังต่อไปนี้ -

<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js" 
   type = "text/javascript"></script>

Note - ในทุกบทของบทช่วยสอนนี้เราได้อ้างถึงไลบรารี KnockoutJS เวอร์ชัน CDN

ตัวอย่าง

KnockoutJS ขึ้นอยู่กับรูปแบบ Model-View-ViewModel (MVVM) เราจะศึกษารูปแบบนี้ในเชิงลึกในบทKnockoutJS - MVVM กรอบ ก่อนอื่นมาดูตัวอย่างง่ายๆของ KnockoutJS

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Simple Example</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
         type = "text/javascript"></script>
   </head>

   <body>
      <!-- This is called "view" of HTML markup that defines the appearance of UI -->

      <p>First String: <input data-bind = "value: firstString" /></p>
      <p>Second String: <input data-bind = "value: secondString" /></p>

      <p>First String: <strong data-bind = "text: firstString">Hi</strong></p>
      <p>Second String: <strong data-bind = "text: secondString">There</strong></p>

      <p>Derived String: <strong data-bind = "text: thirdString"></strong></p>

      <script>
         <!-- This is called "viewmodel". This javascript section defines the data and 
            behavior of UI -->

         function AppViewModel() {
            this.firstString = ko.observable("Enter First String");
            this.secondString = ko.observable("Enter Second String");

            this.thirdString = ko.computed(function() {
               return this.firstString() + " " + this.secondString();
            }, this);
         }

         // Activates knockout.js
         ko.applyBindings(new AppViewModel());
      </script>

   </body>
</html>

บรรทัดต่อไปนี้อ้างถึงไลบรารี KnockoutJS

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"> </script>

บรรทัดนี้หมายถึงไลบรารี KnockoutJS

เรามีช่องป้อนข้อมูลสองช่อง: First String และ Second String. ตัวแปร 2 ตัวนี้เริ่มต้นด้วยค่า Enter First String และ Enter Second String ตามลำดับใน ViewModel

<p>First String: < input data-bind = "value: firstString" /> </p>

นี่คือวิธีที่เราผูกค่าจาก ViewModel ไปยังองค์ประกอบ HTML โดยใช้ 'data-bind' แอตทริบิวต์ในส่วนเนื้อหา

ที่นี่ 'firstString' หมายถึงตัวแปร ViewModel

this.firstString = ko.observable("Enter First String");

ko.observable เป็นแนวคิดที่คอยจับตาดูการเปลี่ยนแปลงค่าเพื่อให้สามารถอัปเดตข้อมูล ViewModel ที่อยู่เบื้องหลังได้

เพื่อให้เข้าใจสิ่งนี้ได้ดีขึ้นเรามาอัปเดตช่องป้อนข้อมูลแรกเป็น "สวัสดี" และช่องป้อนข้อมูลที่สองเป็น "TutorialsPoint" คุณจะเห็นค่าต่างๆได้รับการอัปเดตพร้อมกัน เราจะศึกษาเพิ่มเติมเกี่ยวกับแนวคิดนี้ในบทKnockoutJS - Observables

this.thirdString = ko.computed(function() {
   return this.firstString() + " " + this.secondString();
}, this);

ต่อไปเรามีฟังก์ชันคำนวณใน viewmodel ฟังก์ชันนี้ได้รับสตริงที่สามตาม 2 สตริงที่กล่าวถึงก่อนหน้านี้ ดังนั้นการอัปเดตใด ๆ ที่ทำกับสตริงเหล่านี้จะแสดงในสตริงที่ได้รับนี้โดยอัตโนมัติ ไม่จำเป็นต้องเขียนโค้ดเพิ่มเติมเพื่อทำสิ่งนี้ให้สำเร็จ นี่เป็นเพียงตัวอย่างง่ายๆ เราจะศึกษาเกี่ยวกับแนวคิดนี้ในบทKnockoutJS - Computed Observables

เอาต์พุต

บันทึกรหัสด้านบนเป็น my_first_knockoutjs_program.html. เปิดไฟล์นี้ในเบราว์เซอร์ของคุณและคุณจะเห็นผลลัพธ์ดังต่อไปนี้

แก้ไขสตริงเป็น "Hello" และ "TutorialsPoint" และผลลัพธ์จะเปลี่ยนแปลงดังนี้

KnockoutJS ใช้กันอย่างแพร่หลายสำหรับ Single Page Applications - เว็บไซต์ที่สร้างขึ้นด้วยความสามารถในการดึงข้อมูลที่จำเป็นทั้งหมดแบบไดนามิกด้วยการโหลดหน้าเดียวเพื่อลดการเดินทางไปกลับของเซิร์ฟเวอร์

KnockoutJS เป็นกรอบงานฝั่งไคลเอ็นต์ นี่คือไลบรารี JavaScript ซึ่งทำให้ง่ายต่อการผูก HTML กับข้อมูลโดเมน ใช้รูปแบบที่เรียกว่า Model-View-ViewModel (MVVM) Observables เป็นส่วนผสมมหัศจรรย์ของ KnockoutJS ข้อมูลทั้งหมดยังคงซิงค์เนื่องจากแอตทริบิวต์ที่สังเกตได้

สถาปัตยกรรม

ดู

มุมมองเป็นเพียงส่วนต่อประสานผู้ใช้ที่สร้างขึ้นโดยใช้องค์ประกอบ HTML และสไตล์ CSS

คุณสามารถผูกองค์ประกอบ HTML DOM กับโมเดลข้อมูลโดยใช้ KnockoutJS มีการเชื่อมโยงข้อมูล 2 ทางระหว่าง View และ ViewModel โดยใช้แนวคิด 'data-bind' ซึ่งหมายความว่าการอัปเดตใด ๆ ที่ทำใน UI จะแสดงในโมเดลข้อมูลและการเปลี่ยนแปลงใด ๆ ที่ทำในโมเดลข้อมูลจะแสดงใน UI เราสามารถสร้าง UI ที่อัปเดตด้วยตนเองได้ด้วยความช่วยเหลือของ knockoutJS

ViewModel

ViewModel เป็นอ็อบเจ็กต์ JavaScript ซึ่งมีคุณสมบัติและฟังก์ชันที่จำเป็นในการแสดงข้อมูล View และ ViewModel เชื่อมต่อกันด้วยแนวคิดการผูกข้อมูลแบบเปิดเผยที่ใช้ใน HTML ทำให้ง่ายต่อการเปลี่ยน HTML โดยไม่ต้องเปลี่ยน ViewModel KnockoutJS ดูแลการรีเฟรชข้อมูลอัตโนมัติระหว่างพวกเขาผ่านการใช้ Observables

การซิงโครไนซ์ข้อมูลทำได้โดยการผูกองค์ประกอบ DOM เข้ากับโมเดลข้อมูลโดยใช้การผูกข้อมูลก่อนแล้วจึงรีเฟรชส่วนประกอบทั้ง 2 นี้โดยใช้ Observables การติดตามการพึ่งพาจะทำโดยอัตโนมัติเนื่องจากการซิงโครไนซ์ข้อมูลนี้ ไม่จำเป็นต้องมีการเข้ารหัสเพิ่มเติมเพื่อให้บรรลุ KnockoutJS อนุญาตให้สร้างการเชื่อมต่อโดยตรงระหว่างจอแสดงผลและข้อมูลพื้นฐาน

คุณสามารถสร้างการเชื่อมโยงของคุณเองที่เรียกว่าการผูกแบบกำหนดเองสำหรับพฤติกรรมเฉพาะของแอปพลิเคชัน วิธีนี้ทำให้ Knockout สามารถควบคุมได้โดยตรงว่าคุณต้องการแปลงข้อมูลเป็น HTML อย่างไร

รุ่น

Model คือข้อมูลโดเมนบนเซิร์ฟเวอร์และได้รับการจัดการเมื่อมีการส่ง / รับคำขอจาก ViewModel

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

ส่วนใหญ่ข้อมูลจะถูกบันทึกและโหลดผ่านการโทร Ajax

Model-View-ViewModel (MVVM)เป็นรูปแบบการออกแบบสถาปัตยกรรมสำหรับการพัฒนาซอฟต์แวร์แอปพลิเคชัน MVVM ได้รับการพัฒนาโดย Microsoft Architect John Gossman ในปี 2548 รูปแบบนี้ได้มาจากรูปแบบ Model-View-Controller (MVC) ข้อดีของ MVVM คือแยกส่วนติดต่อผู้ใช้แบบกราฟิกของเลเยอร์แอปพลิเคชันออกจากตรรกะทางธุรกิจ MVVM มีหน้าที่จัดการข้อมูลจากโมเดลต้นแบบในลักษณะที่แสดงและจัดการได้ง่ายมาก ViewModel ใน MVVM แสดงสถานะและการกระทำของ View ในเวอร์ชันนามธรรม

คลาสมุมมองไม่ทราบว่ามีคลาส Model และ ViewModel อยู่รวมทั้ง Model และ ViewModel ไม่ทราบว่า View มีอยู่ โมเดลยังไม่รู้ว่ามี ViewModel และ View อยู่

สถาปัตยกรรม

ดู

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

รุ่น

Model คือข้อมูลโดเมนหรือออบเจ็กต์ทางธุรกิจซึ่งเก็บข้อมูลแบบเรียลไทม์ นางแบบไม่มีพฤติกรรม พฤติกรรมส่วนใหญ่นำไปใช้ในตรรกะทางธุรกิจ

ViewModel

ViewModel เป็นจุดศูนย์กลางซึ่งข้อมูลจากตรรกะการแสดงผลของ Model และ View จะรวมเข้าด้วยกัน ViewModel มีสถานะไดนามิกของข้อมูล มีตัวประสานโดยนัยอยู่ระหว่าง View และ ViewModel เพื่อสื่อสารกัน การรวมนี้รวมข้อมูลที่เปิดเผยและการผูกคำสั่ง การซิงโครไนซ์ View และ ViewModel ทำได้โดยการเชื่อมต่อนี้ การเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นใน View จะแสดงใน ViewModel และในทำนองเดียวกันการเปลี่ยนแปลงใน ViewModel จะแสดงใน View โดยอัตโนมัติ การมีอยู่ของกลไกการผูกแบบ 2 ทางนี้เป็นลักษณะสำคัญของรูปแบบ MVVM นี้

KnockoutJS สร้างขึ้นจากแนวคิดที่สำคัญ 3 ประการดังต่อไปนี้

  • Observables และการติดตามการพึ่งพาระหว่างกัน - องค์ประกอบ DOM เชื่อมต่อกับ ViewModel ผ่าน 'data-bind' พวกเขาแลกเปลี่ยนข้อมูลผ่าน Observables สิ่งนี้จะดูแลการติดตามการพึ่งพาโดยอัตโนมัติ

  • การเชื่อมโยงที่เปิดเผยระหว่าง UI และ ViewModel - องค์ประกอบ DOM เชื่อมต่อกับ ViewModel ผ่านแนวคิด 'data-bind'

  • Templating เพื่อสร้างส่วนประกอบที่ใช้ซ้ำได้ - Templating เป็นวิธีที่มีประสิทธิภาพในการสร้างเว็บแอปพลิเคชันที่ซับซ้อน

เราจะศึกษา Observables ในบทนี้

ตามชื่อที่ระบุเมื่อคุณประกาศข้อมูล / คุณสมบัติ ViewModel เป็น Observable การแก้ไขข้อมูลใด ๆ ในแต่ละครั้งจะได้รับการสะท้อนโดยอัตโนมัติในทุกที่ที่ใช้ข้อมูล นอกจากนี้ยังรวมถึงการรีเฟรชการอ้างอิงที่เกี่ยวข้อง KO ดูแลสิ่งเหล่านี้และไม่จำเป็นต้องเขียนโค้ดเพิ่มเติมเพื่อให้บรรลุเป้าหมายนี้

การใช้ Observable ทำให้ UI และ ViewModel สื่อสารแบบไดนามิกกลายเป็นเรื่องง่ายมาก

ไวยากรณ์

คุณต้องประกาศคุณสมบัติ ViewModel ด้วยฟังก์ชัน ko.observable() เพื่อให้เป็นที่สังเกตได้

this.property = ko.observable('value');

ตัวอย่าง

ลองดูตัวอย่างต่อไปนี้ซึ่งแสดงให้เห็นถึงการใช้ Observable

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Observable Example</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
         type = "text/javascript"></script>
   </head>
   
   <body>
      <!-- This is called "view" of HTML markup that defines the appearance of UI -->

      <p>Enter your name: <input data-bind = "value: yourName" /></p>
      <p>Hi <strong data-bind = "text: yourName"></strong> Good Morning!!!</p>

      <script>
         <!-- This is called "viewmodel". This javascript section defines the data and behavior of UI -->

         function AppViewModel() {
            this.yourName = ko.observable("");
         }

         // Activates knockout.js
         ko.applyBindings(new AppViewModel());
      </script>
   </body>
</html>

บรรทัดต่อไปนี้ใช้สำหรับช่องป้อนข้อมูล ดังจะเห็นได้ว่าเราได้ใช้ data-bind attribute เพื่อผูกค่า yourName กับ ViewModel

<p>Enter your name: <input data-bind = "value: yourName" /> <p>

บรรทัดต่อไปนี้จะพิมพ์ค่าของ yourName โปรดทราบว่าประเภทการผูกข้อมูลที่นี่คือข้อความที่เรากำลังอ่านค่า

<p>Hi <strong data-bind = "text: yourName"></strong> Good Morning!!!</p>

ในบรรทัดต่อไปนี้ ko.observable จะคอยจับตาดูตัวแปร yourName สำหรับการแก้ไขใด ๆ ในข้อมูล เมื่อมีการแก้ไขสถานที่ที่เกี่ยวข้องจะได้รับการอัปเดตด้วยค่าที่แก้ไข เมื่อคุณเรียกใช้รหัสต่อไปนี้ช่องป้อนข้อมูลจะปรากฏขึ้น เมื่อคุณอัปเดตช่องป้อนข้อมูลนั้นค่าใหม่จะสะท้อนหรือรีเฟรชในทุกที่ที่ใช้

this.yourName = ko.observable("");

เอาต์พุต

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

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

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

  • ป้อนชื่อเป็น Scott และสังเกตว่าชื่อนั้นแสดงอยู่ในผลลัพธ์

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

การอ่านและการเขียน Observables

ตารางต่อไปนี้แสดงรายการการอ่านและเขียนซึ่งสามารถทำได้บน Observables

ซีเนียร์ อ่าน / เขียนการดำเนินการและไวยากรณ์
1

Read

ในการอ่านค่าเพียงแค่เรียกคุณสมบัติที่สังเกตได้โดยไม่มีพารามิเตอร์เช่น: AppViewModel.yourName ();

2

Write

หากต้องการเขียน / อัปเดตค่าในคุณสมบัติที่สังเกตได้เพียงส่งค่าที่ต้องการในพารามิเตอร์เช่น: AppViewModel.yourName ('Bob');

3

Write multiple

คุณสมบัติ ViewModel หลายรายการสามารถอัปเดตได้ในแถวเดียวด้วยความช่วยเหลือของ chaining-syntax เช่น: AppViewModel.yourName ('Bob') yourAge (45);

อาร์เรย์ที่สังเกตได้

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

ไวยากรณ์

this.arrayName = ko.observableArray();    // It's an empty array

อาร์เรย์ที่สังเกตได้จะติดตามเฉพาะวัตถุที่เพิ่มหรือลบออก จะไม่แจ้งให้ทราบหากมีการแก้ไขคุณสมบัติของแต่ละวัตถุ

เริ่มต้นเป็นครั้งแรก

คุณสามารถเริ่มต้นอาร์เรย์ของคุณและในเวลาเดียวกันคุณสามารถประกาศว่าเป็น Observable โดยส่งผ่านค่าเริ่มต้นไปยังตัวสร้างดังนี้

this.arrayName = ko.observableArray(['scott','jack']);

การอ่านจากอาร์เรย์ที่สังเกตได้

คุณสามารถเข้าถึงองค์ประกอบอาร์เรย์ที่สังเกตได้ดังต่อไปนี้

alert('The second element is ' + arrayName()[1]);

ฟังก์ชั่น ObservableArray

KnockoutJS มีชุดฟังก์ชันอาร์เรย์ที่สังเกตได้ของตัวเอง สะดวกเพราะ -

  • ฟังก์ชันเหล่านี้ใช้ได้กับทุกเบราว์เซอร์

  • ฟังก์ชันเหล่านี้จะดูแลการติดตามการพึ่งพาโดยอัตโนมัติ

  • ไวยากรณ์ใช้งานง่าย ตัวอย่างเช่นหากต้องการแทรกองค์ประกอบลงในอาร์เรย์คุณต้องใช้ arrayName.push ('value') แทน arrayName (). push ('value')

ต่อไปนี้เป็นรายการวิธีการต่างๆของ Observable Array

ซีเนียร์ วิธีการและคำอธิบาย
1 กด ('ค่า')

แทรกรายการใหม่ที่ท้ายอาร์เรย์

2 ป๊อป ()

ลบรายการสุดท้ายออกจากอาร์เรย์และส่งคืน

3 unshift ('ค่า')

แทรกค่าใหม่ที่จุดเริ่มต้นของอาร์เรย์

4 กะ ()

ลบรายการแรกออกจากอาร์เรย์และส่งคืน

5 ย้อนกลับ ()

กลับลำดับของอาร์เรย์

6 เรียงลำดับ ()

จัดเรียงรายการอาร์เรย์ตามลำดับจากน้อยไปมาก

7 ประกบ (ดัชนีเริ่มต้นดัชนีปลาย)

ยอมรับพารามิเตอร์ 2 ตัวคือ start-index และ end-index - ลบไอเท็มที่เริ่มต้นจากดัชนีเริ่มต้นถึงสิ้นสุดและส่งคืนเป็นอาร์เรย์

8 indexOf ('ค่า')

ฟังก์ชันนี้จะส่งคืนดัชนีของพารามิเตอร์ที่เกิดขึ้นครั้งแรก

9 ชิ้น (ดัชนีเริ่มต้นดัชนีปลาย)

วิธีนี้จะแบ่งส่วนของอาร์เรย์ออก ส่งคืนรายการจากดัชนีเริ่มต้นถึงดัชนีปลาย

10 ลบทั้งหมด()

ลบรายการทั้งหมดและส่งคืนเป็นอาร์เรย์

11 ลบ ('value')

ลบรายการที่ตรงกับพารามิเตอร์และส่งคืนเป็นอาร์เรย์

12 ลบ (ฟังก์ชัน (รายการ) {เงื่อนไข})

ลบรายการที่ตรงตามเงื่อนไขและส่งคืนเป็นอาร์เรย์

13 ลบ ([ชุดค่า])

ลบรายการที่ตรงกับชุดค่าที่กำหนด

14

destroyAll()

ทำเครื่องหมายรายการทั้งหมดในอาร์เรย์ด้วยคุณสมบัติ _destroy ด้วยค่าเป็นจริง

15

destroy('value')

ค้นหารายการที่มีค่าเท่ากับพารามิเตอร์และทำเครื่องหมายด้วยคุณสมบัติพิเศษ _destroy พร้อมค่า true

16

destroy(function(item) { condition})

ค้นหารายการทั้งหมดที่ตรงตามเงื่อนไขทำเครื่องหมายด้วยคุณสมบัติ _destroy ด้วยมูลค่าจริง

17

destroy([set of values])

ค้นหารายการที่ตรงกับชุดค่าที่กำหนดทำเครื่องหมายเป็น _destroy ด้วยค่าจริง

Note - ทำลายและทำลายฟังก์ชันทั้งหมดจาก ObservableArrays ส่วนใหญ่มีไว้สำหรับนักพัฒนา 'Ruby on Rails' เท่านั้น

เมื่อคุณใช้วิธีการทำลายไอเท็มที่เกี่ยวข้องจะไม่ถูกลบออกจากอาร์เรย์ในขณะนั้น แต่ถูกซ่อนไว้โดยการทำเครื่องหมายด้วยคุณสมบัติ_destroyด้วยค่าจริงเพื่อไม่ให้ UI อ่านได้ รายการที่ทำเครื่องหมายเป็น_destroyเท่ากับtrueจะถูกลบในภายหลังในขณะที่จัดการกับกราฟออบเจ็กต์ JSON

Computed Observable เป็นฟังก์ชันที่ขึ้นอยู่กับ Observables ตั้งแต่หนึ่งตัวขึ้นไปและจะอัปเดตโดยอัตโนมัติเมื่อใดก็ตามที่ Observables (การอ้างอิง) ที่เป็นพื้นฐานมีการเปลี่ยนแปลง

เครื่องสังเกตการณ์ที่คำนวณได้สามารถล่ามโซ่ได้

ไวยากรณ์

this.varName = ko.computed(function(){
   ...
   ... //  function code
   ...
},this);

ตัวอย่าง

ให้เราดูตัวอย่างต่อไปนี้ซึ่งแสดงให้เห็นถึงการใช้ Computed Observables

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Computed Observables</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"></script>
   </head>

   <body>
      <p>Enter first number: <input data-bind = "value: a" /></p>
      <p>Enter second number: <input data-bind = "value: b"/></p>
      <p>Average := <span data-bind="text: totalAvg"></span></p>

      <script>
         function MyViewModel() {
            this.a = ko.observable(10);
            this.b = ko.observable(40);

            this.totalAvg = ko.computed(function() {

               if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
                  this.a(Number(this.a()));   //convert string to Number
                  this.b(Number(this.b()));   //convert string to Number
               }

               total = (this.a() + this.b())/2 ;
               return total;
            },this);
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

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

<p>Enter first number: <input data-bind = "value: a" /></p>
<p>Enter second number: <input data-bind = "value: b"/></p>
<p>Average := <span data-bind = "text: totalAvg"></span></p>

ในบรรทัดต่อไปนี้ประเภทของ Observables a และ bเป็นตัวเลขเมื่อเริ่มต้นเป็นครั้งแรกภายใน ViewModel อย่างไรก็ตามใน KO ทุกอินพุตที่ยอมรับจาก UI จะเป็นค่าเริ่มต้นในรูปแบบ String ดังนั้นจึงต้องแปลงเป็น Number เพื่อดำเนินการคำนวณทางคณิตศาสตร์

this.totalAvg = ko.computed(function() {
   
   if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
      this.a(Number(this.a()));   //convert string to Number
      this.b(Number(this.b()));   //convert string to Number
   }
   
   total = (this.a() + this.b())/2 ;
   return total;
},this);

ในบรรทัดต่อไปนี้ค่าเฉลี่ยที่คำนวณได้จะแสดงใน UI โปรดทราบว่าประเภทการผูกข้อมูลของ totalAvg เป็นเพียงข้อความ

<p>Average := <span data-bind = "text: totalAvg"></span></p>

เอาต์พุต

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

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

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

  • ป้อนตัวเลข 2 ตัวในกล่องข้อความและสังเกตว่ามีการคำนวณค่าเฉลี่ย

การจัดการ "นี่"

โปรดทราบว่าในตัวอย่างข้างต้นพารามิเตอร์ที่สองถูกจัดเตรียมไว้เป็น thisเป็นฟังก์ชันคำนวณ ไม่สามารถอ้างถึง Observables ได้a() และ b() โดยไม่ต้องให้ this.

เพื่อเอาชนะสิ่งนี้ self ตัวแปรถูกใช้ซึ่งเก็บข้อมูลอ้างอิงของ this. การทำเช่นนั้นไม่จำเป็นต้องติดตามthisตลอดรหัส แทน,self สามารถใช้ได้.

โค้ด ViewModel ต่อไปนี้ถูกเขียนใหม่สำหรับตัวอย่างข้างต้นโดยใช้ self

function MyViewModel(){
   self = this;
   self.a = ko.observable(10);
   self.b = ko.observable(40);

   this.totalAvg = ko.computed(function() {
      
      if(typeof(self.a()) !== "number" || typeof(self.b()) !== "number") {
         self.a(Number(self.a()));   //convert string to Number
         self.b(Number(self.b()));   //convert string to Number
      }
      
      total = (self.a() + self.b())/2 ;
      return total;
   });
}

เครื่องสังเกตการณ์ที่คำนวณได้บริสุทธิ์

ควรประกาศ Computed Observable เป็น PureComputed Observable ถ้า Observable นั้นเป็นเพียงการคำนวณและส่งคืนค่าและไม่ได้ปรับเปลี่ยนวัตถุหรือสถานะอื่นโดยตรง Pure Computed Observables ช่วยให้ Knockout จัดการการประเมินค่าใหม่และการใช้หน่วยความจำได้อย่างมีประสิทธิภาพ

การแจ้งเตือนสมาชิกอย่างชัดเจน

เมื่อ Computed Observable ส่งคืนค่าชนิดข้อมูลดั้งเดิม (String, Boolean, Null และ Number) ผู้ติดตามจะได้รับแจ้งหากมีการเปลี่ยนแปลงค่าจริงเท่านั้น หมายความว่าหาก Observable ได้รับค่าเดียวกันกับค่าก่อนหน้าสมาชิกจะไม่ได้รับแจ้ง

คุณสามารถทำให้ Computed Observables แจ้งผู้สังเกตการณ์อย่างชัดเจนได้เสมอแม้ว่าค่าใหม่จะเหมือนกับค่าเก่าโดยใช้ notify ไวยากรณ์ดังนี้

myViewModel.property = ko.pureComputed(function() {
   return ...;    // code logic goes here
}).extend({ notify: 'always' });

การ จำกัด การแจ้งเตือนการเปลี่ยนแปลง

การอัปเดตที่มีราคาแพงมากเกินไปอาจทำให้เกิดปัญหาด้านประสิทธิภาพ คุณสามารถ จำกัด จำนวนการแจ้งเตือนที่จะได้รับจาก Observable โดยใช้rateLimit แอตทริบิวต์ดังนี้

// make sure there are updates no more than once per 100-millisecond period
myViewModel.property.extend({ rateLimit: 100 });

การค้นหาว่าทรัพย์สินสามารถสังเกตได้จากการคำนวณหรือไม่

ในบางสถานการณ์อาจจำเป็นต้องค้นหาว่าคุณสมบัติเป็นสิ่งที่สังเกตได้จากการคำนวณหรือไม่ ฟังก์ชันต่อไปนี้สามารถใช้เพื่อระบุประเภทของ Observables

ซีเนียร์ ฟังก์ชัน
1

ko.isComputed

ผลตอบแทน true หากคุณสมบัตินั้นสามารถสังเกตได้จากการคำนวณ

2

ko.isObservable

ผลตอบแทน true ถ้าคุณสมบัติเป็น Observable อาร์เรย์ที่สังเกตได้หรือ Computed Observable

3

ko.isWritableObservable

ผลตอบแทน trueถ้าสังเกตได้อาร์เรย์ที่สังเกตได้หรือคอมพิวเตอร์ที่สังเกตได้ที่เขียนได้ (เรียกอีกอย่างว่า ko.isWriteableObservable)

สิ่งที่สังเกตได้จากการคำนวณที่เขียนได้

Computed Observable มาจาก Observables อื่น ๆ หนึ่งตัวหรือหลายตัวดังนั้นจึงอ่านได้อย่างเดียว อย่างไรก็ตามเป็นไปได้ว่าเราสามารถทำให้ Computed Observable เขียนได้ สำหรับสิ่งนี้คุณต้องจัดเตรียมฟังก์ชันการโทรกลับที่ทำงานกับค่าที่เขียน

Computed Observables ที่เขียนได้เหล่านี้ทำงานเหมือนกับ Observables ทั่วไป นอกจากนี้ยังต้องการตรรกะที่กำหนดเองเพื่อสร้างขึ้นเพื่อรบกวนการดำเนินการอ่านและเขียน

เราสามารถกำหนดค่าให้กับคุณสมบัติ Observables หรือ Computed Observable จำนวนมากโดยใช้ไวยากรณ์การเชื่อมโยงดังนี้

myViewModel.fullName('Tom Smith').age(45)

ตัวอย่าง

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้ Writable Computable Observable

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Writable Computed Observable</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
   </head>

   <body>
      <p>Enter your birth Date: <input type = "date" data-bind = "value: rawDate" ></p>
      <p><span data-bind = "text: yourAge"></span></p>

      <script>
         function MyViewModel() {
            this.yourAge = ko.observable();
            today = new Date();
            rawDate = ko.observable();

            this.rawDate = ko.pureComputed ({

               read: function() {
                  return this.yourAge;
               },

               write: function(value) {
                  var b = Date.parse(value);    // convert birth date into milliseconds
                  var t = Date.parse(today);    // convert todays date into milliseconds
                  diff = t - b;                 // take difference
                  var y = Math.floor(diff/31449600000);     // difference is converted
                                                            // into years. 31449600000
                                                            //milliseconds form a year.

                  var m = Math.floor((diff % 31449600000)/604800000/4.3);  // calculating
                                                                           // months.
                                                                           // 604800000
                                                                           // milliseconds
                                                                           // form a week.

                  this.yourAge("You are " + y + " year(s) " + m +" months old.");
               },
               owner: this
            });
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

ในโค้ดด้านบน rawDate เป็นคุณสมบัติ pureComputed ที่ยอมรับจาก UI yourAge สังเกตได้มาจาก rawDate.

วันที่ใน JavaScript ถูกจัดการเป็นมิลลิวินาที ดังนั้นวันที่ทั้งสอง (วันที่วันนี้และวันเกิด) จะถูกแปลงเป็นมิลลิวินาทีจากนั้นความแตกต่างระหว่างวันเหล่านั้นจะถูกแปลงเป็นปีและเดือน

เอาต์พุต

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

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

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

  • ป้อนวันเกิดใด ๆ และสังเกตว่ามีการคำนวณอายุ

การผูกแบบประกาศใน KnockoutJS เป็นวิธีที่มีประสิทธิภาพในการเชื่อมต่อข้อมูลกับ UI

สิ่งสำคัญคือต้องเข้าใจความสัมพันธ์ระหว่างการผูกและ Observables ในทางเทคนิคทั้งสองแตกต่างกัน คุณสามารถใช้ออบเจ็กต์ JavaScript ปกติเป็น ViewModel และ KnockoutJS สามารถประมวลผลการโยงของ View ได้อย่างถูกต้อง

หากไม่มีสิ่งที่สังเกตได้คุณสมบัติจาก UI จะถูกประมวลผลในครั้งแรกเท่านั้น ในกรณีนี้จะไม่สามารถอัปเดตโดยอัตโนมัติตามการอัปเดตข้อมูลพื้นฐาน เพื่อให้บรรลุสิ่งนี้การผูกต้องอ้างถึงคุณสมบัติที่สังเกตได้

ไวยากรณ์การผูก

การเข้าเล่มประกอบด้วย 2 รายการคือการเข้าเล่ม name และ value. ต่อไปนี้เป็นตัวอย่างง่ายๆ -

Today is : <span data-bind = "text: whatDay"></span>

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

Your name: <input data-bind = "value: yourName, valueUpdate: 'afterkeydown'" />

ที่นี่ค่าจะได้รับการอัปเดตหลังจากกดแต่ละปุ่ม

ค่าผูกมัด

ค่าการผูกสามารถเป็น single value, literal, ก variable หรือสามารถเป็น JavaScriptนิพจน์. หากการเชื่อมโยงอ้างถึงนิพจน์หรือการอ้างอิงที่ไม่ถูกต้อง KO จะสร้างข้อผิดพลาดและหยุดประมวลผลการเชื่อมโยง

ต่อไปนี้เป็นตัวอย่างบางส่วนของการผูก

<!-- simple text binding -->
<p>Enter employee name: <input   -bind = 'value: empName' /></p>

<!-- click binding, call a specific function -->
<button data-bind="click: sortEmpArray">Sort Array</button>

<!-- options binding -->
<select multiple = "true" size = "8" data-bind = "options: empArray , 
   selectedOptions: chosenItem"> </select>

สังเกตประเด็นต่อไปนี้ -

  • ช่องว่างไม่ได้สร้างความแตกต่างใด ๆ

  • เริ่มจาก KO 3.0 คุณสามารถข้ามค่าการผูกซึ่งจะทำให้การผูกเป็นค่าที่ไม่ได้กำหนด

บริบทการผูก

ข้อมูลที่ใช้ในการเชื่อมโยงปัจจุบันสามารถอ้างอิงได้โดยออบเจ็กต์ วัตถุนี้เรียกว่าbinding context.

ลำดับชั้นบริบทถูกสร้างและจัดการโดย KnockoutJS โดยอัตโนมัติ ตารางต่อไปนี้แสดงรายการบริบทการเชื่อมโยงประเภทต่างๆที่จัดเตรียมโดย KO

ซีเนียร์ ประเภทบริบทที่มีผลผูกพันและคำอธิบาย
1

$root

สิ่งนี้หมายถึง ViewModel ระดับบนสุดเสมอ ทำให้สามารถเข้าถึงเมธอดระดับบนสุดสำหรับจัดการ ViewModel โดยปกติจะเป็นวัตถุที่ส่งผ่านไปยัง ko.applyBindings

2

$data

คุณสมบัตินี้เป็นจำนวนมากเช่น thisคำสำคัญในวัตถุ Javascript คุณสมบัติ $ data ในบริบทที่มีผลผูกพันหมายถึงอ็อบเจ็กต์ ViewModel สำหรับบริบทปัจจุบัน

3

$index

คุณสมบัตินี้มีดัชนีของรายการปัจจุบันของอาร์เรย์ภายใน foreach loop ค่าของดัชนี $ จะเปลี่ยนโดยอัตโนมัติเมื่อและเมื่อมีการอัปเดตอาร์เรย์ที่สังเกตได้ เห็นได้ชัดว่าบริบทนี้มีให้สำหรับไฟล์foreach การผูก

4

$parent

คุณสมบัตินี้อ้างถึงอ็อบเจ็กต์ ViewModel พาเรนต์ สิ่งนี้มีประโยชน์เมื่อคุณต้องการเข้าถึงคุณสมบัติ ViewModel ภายนอกจากด้านในของลูปที่ซ้อนกัน

5

$parentContext

เรียกอ็อบเจ็กต์บริบทที่ถูกผูกไว้ที่ระดับพาเรนต์ $parentContext. ซึ่งแตกต่างจาก$parent. $ parent หมายถึงข้อมูล ในขณะที่$ parentContextหมายถึงบริบทที่มีผลผูกพัน เช่นคุณอาจต้องเข้าถึงดัชนีของรายการ foreach ด้านนอกจากบริบทภายใน

6

$rawdata

บริบทนี้เก็บค่า ViewModel ดิบในสถานการณ์ปัจจุบัน สิ่งนี้คล้ายกับ$data but the difference is, if ViewModel is wrapped in Observable, then $ข้อมูลกลายเป็นเพียงแค่ไม่ได้รับการห่อหุ้ม ViewModel และ $ rawdata กลายเป็นข้อมูลที่สังเกตได้จริง

7

$component

บริบทนี้ใช้เพื่ออ้างถึง ViewModel ของส่วนประกอบนั้นเมื่อคุณอยู่ภายในส่วนประกอบเฉพาะ เช่นคุณอาจต้องการเข้าถึงคุณสมบัติบางอย่างจาก ViewModel แทนข้อมูลปัจจุบันในส่วนเทมเพลตของคอมโพเนนต์

8

$componentTemplateNodes

สิ่งนี้แสดงถึงอาร์เรย์ของโหนด DOM ที่ส่งผ่านไปยังส่วนประกอบนั้น ๆ เมื่อคุณอยู่ภายในเทมเพลตส่วนประกอบเฉพาะ

คำศัพท์ต่อไปนี้มีให้ใช้ในการผูก แต่ไม่มีผลผูกพันตามบริบท

  • $context - นี่ไม่ใช่อะไรนอกจากอ็อบเจ็กต์บริบทที่มีผลผูกพันที่มีอยู่

  • $element - วัตถุนี้อ้างถึงองค์ประกอบใน DOM ในการเชื่อมโยงปัจจุบัน

การทำงานกับข้อความและลักษณะที่ปรากฏ

ต่อไปนี้เป็นรายการประเภทการผูกที่ KO จัดเตรียมไว้เพื่อจัดการกับข้อความและลักษณะที่มองเห็นได้

ซีเนียร์ ประเภทการผูกและการใช้งาน
1 มองเห็นได้:

เพื่อแสดงหรือซ่อนองค์ประกอบ HTML DOM ขึ้นอยู่กับเงื่อนไขบางประการ

2 ข้อความ:

เพื่อตั้งค่าเนื้อหาขององค์ประกอบ HTML DOM

3 html:

เพื่อตั้งค่าเนื้อหามาร์กอัป HTML ขององค์ประกอบ DOM

4 css:

เพื่อใช้คลาส CSS กับองค์ประกอบ

5 สไตล์:

เพื่อกำหนดแอตทริบิวต์สไตล์อินไลน์ขององค์ประกอบ

6 attr:

เพื่อเพิ่มแอตทริบิวต์ให้กับองค์ประกอบแบบไดนามิก

Working with Control Flow Bindings

Following is a list of Control Flow Binding types provided by KO.

Sr.No. Binding Type & Usage
1 foreach:

In this binding, each array item is referenced in HTML markup in a loop.

2 if:

If the condition is true, then the given HTML markup will be processed. Else, it will be removed from DOM.

3 ifnot:

Negation of If. If the condition is true, then the given HTML markup will be processed. Else, it will be removed from DOM.

4 with:

This binding is used to bind the child elements of an object in the specified object's context.

5 component: OR component:

This binding is used to insert a component into DOM elements and pass the parameters optionally.

Working with Form Fields Bindings

Following is the list of Form Fields Binding types provided by KO.

Sr.No. Binding Type & Usage
1 click:

This binding is used to invoke a JavaScript function associated with a DOM element based on a click.

2 event:

This binding is used to listen to the specified DOM events and call associated handler functions based on them.

3 submit:

This binding is used to invoke a JavaScript function when the associated DOM element is submitted.

4 enable:

This binding is used to enable certain DOM elements based on a specified condition.

5 disable:

This binding disables the associated DOM element when the parameter evaluates to true.

6 value:

This binding is used to link respective DOM element's value into ViewModel property.

7 textInput:

This binding is used to create 2-way binding between text box or textarea and ViewModel property.

8 hasFocus:

This binding is used to manually set the focus of a HTML DOM element through a ViewModel property.

9 checked:

This binding is used to create a link between a checkable form element and ViewModel property.

10 options:

This binding is used to define the options for a select element.

11 selectedOptions:

This binding is used to work with elements which are selected currently in multi list select form control.

12 uniqueName:

This binding is used to generate a unique name for a DOM element.

KnockoutJs automatically tracks the dependencies when the values get updated. It has a single object called dependency tracker (ko.dependencyDetection) which acts as an intermediate between the two parties for subscribing the dependencies.

Following is the algorithm for dependency tracking.

Step 1 − Whenever you declare a computed observable, KO immediately invokes its evaluator function to get its initial value.

Step 2 − Subscription is set up to any observable that the evaluator reads. In an application, the old subscriptions which are no longer used are disposed.

Step 3 − KO finally notifies the updated computed observable.

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJS How Dependency Tracking Works</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div>
         <form data-bind = "submit: addFruits">
            <b>Add Fruits:</b>
            <input data-bind = 'value: fruitToAdd, valueUpdate: "afterkeydown"'/>
            <button type = "submit" data-bind = "enable: fruitToAdd().length > 0">Add</button>
            <p><b>Your fruits list:</b></p>
            <select multiple = "multiple" width = "50" data-bind = "options: fruits"> </select>
         </form>
      </div>
      
      <script>
         var Addfruit = function(fruits) {
            this.fruits = ko.observableArray(fruits);
            this.fruitToAdd = ko.observable("");
            
            this.addFruits = function() {
               
               if (this.fruitToAdd() != "") {
                  this.fruits.push(this.fruitToAdd());   // Adds a fruit
                  this.fruitToAdd("");                   // Clears the text box
               }
                
            }.bind(this);                                // "this" is the view model
         };

         ko.applyBindings(new Addfruit(["Apple", "Orange", "Banana"]));
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in dependency_tracking.htm file.

  • Open this HTML file in a browser.

  • Enter any fruit name and click the Add button.

Controlling Dependencies Using Peek

The Computed Observable can be accessed without creating a dependency, by using the peek function. It controls the Observable by updating the computed property.

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJs Controlling Dependencies Using Peek</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div class = "logblock">
         <h3>Computed Log</h3>
         <pre class = "log" data-bind = "html: computedLog"></pre>
      </div>

      <script>
         function AppData() {
            this.firstName = ko.observable('John');
            this.lastName = ko.observable('Burns');
            this.computedLog = ko.observable('Log: ');
            
            this.fullName = ko.computed(function () {
               var value = this.firstName() + " " + this.lastName();
               this.computedLog(this.computedLog.peek() + value + '; <br/>');
               return value;
            }, this);

            this.step = ko.observable(0);
            this.next = function () {
               this.step(this.step() === 2 ? 0 : this.step()+1);
            };
         };
         
         ko.applyBindings(new AppData());
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in dependency_tracking_peek.htm file.

  • Open this HTML file in a browser.

Observations

Ignoring Dependencies Within a Computed Dependency

The ko.ignoreDependencies function helps ignore those dependencies that you don't want to track within the computed dependencies. Following is its syntax.

ko.ignoreDependencies( callback, callbackTarget, callbackArgs );

Why Circular Dependencies Aren't Meaningful

If KO is evaluating a Computed Observable, then it will not restart an evaluation of the dependent Computed Observable. Hence, it doesn't make sense to include cycles in your dependency chains.

Template is a set of DOM elements which can be used repetitively. Templating makes it easy to build complex applications due to its property of minimizing duplication of DOM elements.

There are 2 ways of creating templates.

  • Native templating − This method supports the control flow bindings such as foreach, with, and if. These bindings capture HTML markup existing in the element and use it as template for random items. No external library is required for this templating.

  • String-based templating − KO connects to the third party engine to pass ViewModel values into it and injects the resulting markup into the document. For example, JQuery.tmpl and Underscore Engine.

Syntax

template: <parameter-value>

<script type = "text/html" id = "template-name">
   ...
   ...   // DOM elemets to be processed
   ...
</script>

โปรดทราบว่า type จัดให้เป็น text/html ในบล็อกสคริปต์เพื่อแจ้งให้ KO ทราบว่าไม่ใช่บล็อกที่เรียกใช้งานได้แทนที่จะเป็นเพียงบล็อกเทมเพลตที่ต้องแสดงผล

Parameters

การรวมคุณสมบัติต่อไปนี้สามารถส่งเป็นค่าพารามิเตอร์ไปยังเทมเพลต

  • name - นี่แสดงถึงชื่อของเทมเพลต

  • nodes- แสดงอาร์เรย์ของโหนด DOM ที่จะใช้เป็นเทมเพลต พารามิเตอร์นี้จะถูกละเว้นหากส่งผ่านพารามิเตอร์ name

  • data - นี่ไม่ใช่อะไรเลยนอกจากข้อมูลที่จะแสดงผ่านเทมเพลต

  • if - เทมเพลตจะแสดงผลหากเงื่อนไขที่กำหนดให้ผลลัพธ์เป็นค่าจริงหรือเหมือนจริง

  • foreach - เพื่อให้บริการแม่แบบในรูปแบบ foreach

  • as - นี่เป็นเพียงการสร้างนามแฝงในองค์ประกอบ foreach

  • afterAdd, afterRender, beforeRemove - ทั้งหมดนี้แสดงถึงฟังก์ชันที่เรียกได้ที่จะเรียกใช้ขึ้นอยู่กับการดำเนินการที่ดำเนินการ

ข้อสังเกต

การแสดงเทมเพลตที่มีชื่อ

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

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Named Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', data: friend1 }"></div>
      <div data-bind = "template: { name: 'friend-template', data: friend2 }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friend1 = { 
               name: 'Smith', 
               contactNumber: 4556750345, 
               email: '[email protected]' 
            };
            
            this.friend2 = { 
               name: 'Jack', 
               contactNumber: 6789358001, 
               email: '[email protected]' 
            };
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

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

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

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

  • ที่นี่มีการใช้เทมเพลตเพื่อน 2 ครั้ง

ใช้ "foreach" ในเทมเพลต

ต่อไปนี้เป็นตัวอย่างการใช้งาน foreach พารามิเตอร์พร้อมกับชื่อเทมเพลต

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - foreach used with Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', foreach: friends }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = [
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
               { name: 'Lisa', contactNumber: 4567893131, email: '[email protected]' }
            ]
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

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

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

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

  • ที่นี่การควบคุม foreach ถูกใช้ในการผูกเทมเพลต

การสร้างนามแฝงโดยใช้เป็นคำหลักสำหรับ foreach Items

ต่อไปนี้เป็นวิธีสร้างนามแฝงสำหรับรายการ foreach -

<div data-bind = "template: { 
   name: 'friend-template', 
   foreach: friends, 
   as: 'frnz' 
}"></div>

มันกลายเป็นเรื่องง่ายที่จะอ้างถึงออบเจ็กต์หลักจากด้านในของ foreach ลูปโดยการสร้างนามแฝง คุณลักษณะนี้มีประโยชน์เมื่อโค้ดมีความซับซ้อนและซ้อนกันในหลายระดับ

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - using alias in Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <ul data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends, 
         as: 'frnz' 
      }"></ul>

      <script type = "text/html" id = "friend-template">
         <li>
            <h3 data-bind = "text: name"></h3>
            <span>Contact Numbers</span>
            <ul data-bind = "template: { 
               name : 'contacts-template', 
               foreach:contactNumber, 
               as: 'cont'
            } "></ul>
            <p>Email-id: <span data-bind = "text: email"></span></p>
         </li>
      </script>

      <script type = "text/html" id = "contacts-template">
         <li>
            <p><span data-bind = "text: cont"></span></p>
         </li>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = ko.observableArray ( [
               { 
                  name: 'Smith', 
                  contactNumber: [ 4556750345, 4356787934 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Jack', 
                  contactNumber: [ 6789358001, 3456895445 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Lisa', 
                  contactNumber: [ 4567893131, 9876456783, 1349873445 ],  
                  email: '[email protected]' 
               }
            ]);
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

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

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

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

  • นามแฝงใช้แทนชื่อเต็มของอาร์เรย์

ใช้ afterAdd, beforeRemove และ afterRender

มีสถานการณ์ที่จำเป็นต้องเรียกใช้ตรรกะที่กำหนดเองเพิ่มเติมบนองค์ประกอบ DOM ที่สร้างโดยเทมเพลต ในกรณีเช่นนี้สามารถใช้การโทรกลับต่อไปนี้ได้ พิจารณาว่าคุณกำลังใช้องค์ประกอบ foreach แล้ว -

afterAdd - ฟังก์ชันนี้ถูกเรียกใช้เมื่อมีการเพิ่มรายการใหม่ลงในอาร์เรย์ที่กล่าวถึงใน foreach

beforeRemove - ฟังก์ชันนี้ถูกเรียกใช้ก่อนที่จะลบรายการออกจากอาร์เรย์ที่กล่าวถึงใน foreach

afterRender - ฟังก์ชันที่กล่าวถึงที่นี่จะถูกเรียกใช้ทุกครั้งที่แสดงผล foreach และมีการเพิ่มรายการใหม่ในอาร์เรย์

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Use of afterRender Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
      <script src = "https://code.jquery.com/jquery-2.1.3.min.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends , 
         afterRender: afterProcess
      }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
         <button data-bind = "click: $root.removeContact">remove </button>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            self = this;
            this.friends = ko.observableArray ([
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
            ])

            this.afterProcess = function(elements, data){
               $(elements).css({color: 'magenta' });
            }

            self.removeContact = function() {
               self.friends.remove(this);
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
   </body>
</html>

Output

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

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

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

  • ที่นี่ฟังก์ชัน afterProcess จะถูกเรียกใช้งานทุกครั้งที่แสดงผล foreach

การเลือกเทมเพลตแบบไดนามิก

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

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Dynamic Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: whichTemplate, 
         foreach: friends 
      }"></div>

      <script type = "text/html" id = "only-phon">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
      </script>

      <script type = "text/html" id = "only-email">
         <h3 data-bind = "text: name"></h3>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
   
            this.friends = ko.observableArray ([
               {
                  name: 'Smith', 
                  contactNumber: 4556750345, 
                  email: '[email protected]', 
                  active: ko.observable(true)
               },
               
               {
                  name: 'Jack', 
                  contactNumber: 6789358001, 
                  email: '[email protected]', 
                  active: ko.observable(false)
               },
            ]);

            this.whichTemplate = function(friends) {
               return friends.active() ? "only-phon" : "only-email";
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

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

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

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

  • เทมเพลตที่จะใช้จะถูกกำหนดขึ้นอยู่กับค่าสถานะที่ใช้งานอยู่

การใช้เอ็นจิ้นที่ใช้สตริงภายนอก

เทมเพลตเนทีฟทำงานได้อย่างสมบูรณ์แบบกับองค์ประกอบโฟลว์การควบคุมที่หลากหลายแม้จะมีบล็อกโค้ดที่ซ้อนกัน KO ยังนำเสนอวิธีการรวมกับไลบรารีเทมเพลตภายนอกเช่น Underscore templating Engine หรือ JQuery.tmpl

ดังที่กล่าวไว้ในเว็บไซต์อย่างเป็นทางการ JQuery.tmpl ไม่ได้อยู่ระหว่างการพัฒนาอีกต่อไปตั้งแต่เดือนธันวาคม 2554 ดังนั้นขอแนะนำให้ใช้เทมเพลตเนทีฟของ KO แทน JQuery.tmpl หรือเอ็นจิ้นเทมเพลตที่อิงสตริงอื่น ๆ

โปรดดูเว็บไซต์อย่างเป็นทางการสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้

ส่วนประกอบเป็นวิธีการจัดการโค้ด 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 หลัก พาเรนต์ 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 โดยใช้ตรรกะที่กำหนดเอง