KnockoutJS - Hướng dẫn nhanh

KnockoutJS về cơ bản là một thư viện được viết bằng JavaScript, dựa trên mẫu MVVM giúp các nhà phát triển xây dựng các trang web phong phú và đáp ứng. Mô hình phân tách Mô hình của ứng dụng (dữ liệu được lưu trữ), Chế độ xem (Giao diện người dùng) và Mô hình Chế độ xem (Biểu diễn JavaScript của mô hình).

KnockoutJS được phát triển và duy trì như một dự án mã nguồn mở bởi Steve Sanderson, một nhân viên của Microsoft vào ngày 5 tháng 7 năm 2010. KO là tên viết tắt được sử dụng cho KnockoutJS. KO hỗ trợ tất cả các trình duyệt chính - IE 6+, Firefox 3.5+, Chrome, Opera, Safari (máy tính để bàn / di động).

Đặc điểm của KnockoutJS

Dưới đây là danh sách một số tính năng nổi bật nhất của KnockoutJS -

  • Declarative Binding- Các phần tử DOM HTML được kết nối với mô hình thông qua thuộc tính data-bind bằng một cú pháp rất đơn giản. Nó được thực hiện dễ dàng để đạt được phản hồi bằng cách sử dụng tính năng này.

  • Automatic UI Refresh- Bất kỳ thay đổi nào được thực hiện để xem dữ liệu mô hình được phản ánh tự động trong giao diện người dùng và ngược lại. Không cần viết thêm mã.

  • Dependency Tracking- Mối quan hệ giữa các thuộc tính KO và các chức năng / thành phần của thư viện KO là minh bạch. Tự động theo dõi các thay đổi dữ liệu trong thuộc tính KO và cập nhật các khu vực bị ảnh hưởng tương ứng.

  • Templating - Mẫu là một cách đơn giản và thuận tiện để xây dựng các cấu trúc giao diện người dùng phức tạp - với khả năng lặp lại hoặc lồng các khối - như một chức năng xem dữ liệu mô hình.

  • Extensible - Mở rộng hành vi tùy chỉnh rất dễ dàng.

Tại sao sử dụng KnockoutJS?

  • Thư viện KnockoutJS cung cấp một cách dễ dàng và sạch sẽ để xử lý các giao diện hướng dữ liệu phức tạp. Người ta có thể tạo giao diện người dùng tự cập nhật cho các đối tượng Javascript.

  • Nó là Thư viện JavaScript thuần túy và hoạt động với bất kỳ khuôn khổ web nào. Nó không thay thế JQuery nhưng có thể hoạt động như một phần bổ sung cung cấp các tính năng thông minh.

  • Tệp thư viện KnockoutJS rất nhỏ và nhẹ.

  • KnockoutJS độc lập với bất kỳ khuôn khổ nào khác. Nó tương thích với các công nghệ phía máy khách hoặc máy chủ khác.

  • Quan trọng nhất của tất cả KnockoutJS là mã nguồn mở và do đó miễn phí để sử dụng.

  • KnockoutJS được ghi lại đầy đủ. Trang web chính thức có tài liệu đầy đủ bao gồm tài liệu API, ví dụ trực tiếp và hướng dẫn tương tác.

Nó rất dễ sử dụng KnockoutJS. Chỉ cần tham khảo tệp JavaScript bằng thẻ <script> trong các trang HTML.

Knockout.js có thể được truy cập theo những cách sau:

  • Bạn có thể tải xuống bản dựng sản xuất của Knockout.js từ trang web chính thức của nó

    Một trang như trong hình sau sẽ được hiển thị. Nhấp vào liên kết tải xuống và bạn sẽ nhận được tệp knockout.js mới nhất.

Bây giờ hãy tham khảo tệp như được hiển thị trong đoạn mã sau.

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

Cập nhật thuộc tính src để khớp với vị trí lưu giữ các tệp đã tải xuống.

  • Bạn có thể tham khảo thư viện KnockoutJS từ CDN -

    • Bạn có thể tham khảo thư viện KnockoutJS từ Microsoft Ajax CDN trong mã của mình như sau:

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"></script>
  • Ngoài ra, bạn có thể tham khảo phiên bản thu nhỏ của thư viện KnockoutJS từ CDNJS như sau:

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

Note - Trong tất cả các chương của hướng dẫn này, chúng tôi đã đề cập đến phiên bản CDN của thư viện KnockoutJS.

Thí dụ

KnockoutJS dựa trên mẫu Model-View-ViewModel (MVVM). Chúng ta sẽ nghiên cứu sâu về mô hình này trong chương KnockoutJS - MVVM Framework . Đầu tiên chúng ta hãy xem một ví dụ đơn giản về 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>

Dòng sau đề cập đến thư viện KnockoutJS.

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

Dòng này đề cập đến thư viện KnockoutJS.

Chúng tôi có hai hộp đầu vào: First StringSecond String. 2 biến này được khởi tạo với giá trị Enter First String và Enter Second String tương ứng trong ViewModel.

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

Đây là cách chúng tôi liên kết các giá trị từ ViewModel với các phần tử HTML bằng cách sử dụng 'data-bind' thuộc tính trong phần nội dung.

Ở đây, 'firstString' đề cập đến biến ViewModel.

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

ko.observable là một khái niệm theo dõi các thay đổi giá trị để nó có thể cập nhật dữ liệu ViewModel bên dưới.

Để hiểu rõ hơn điều này, hãy cập nhật hộp nhập đầu tiên thành "Xin chào" và hộp nhập thứ hai thành "TutorialsPoint". Bạn sẽ thấy các giá trị được cập nhật đồng thời. Chúng ta sẽ nghiên cứu thêm về khái niệm này trong chương KnockoutJS - Observables .

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

Tiếp theo, chúng ta đã tính toán hàm trong viewmodel. Hàm này dẫn xuất chuỗi thứ ba dựa trên 2 chuỗi đã đề cập trước đó. Do đó, mọi cập nhật được thực hiện cho các chuỗi này sẽ tự động được phản ánh trong chuỗi dẫn xuất này. Không cần phải viết thêm mã để thực hiện điều này. Đây chỉ là một ví dụ đơn giản. Chúng ta sẽ nghiên cứu về khái niệm này trong chương KnockoutJS - Computed Observables .

Đầu ra

Lưu mã trên dưới dạng my_first_knockoutjs_program.html. Mở tệp này trong trình duyệt của bạn và bạn sẽ thấy đầu ra như sau.

Sửa đổi chuỗi thành "Hello" và "TutorialsPoint" và kết quả thay đổi như sau.

KnockoutJS được sử dụng rộng rãi cho các Ứng dụng Trang Đơn - Một trang web được tạo với khả năng truy xuất tất cả các dữ liệu cần thiết một cách linh hoạt với một trang duy nhất giúp giảm các chuyến đi vòng quanh máy chủ.

KnockoutJS là một khuôn khổ phía máy khách. Đây là một thư viện JavaScript giúp liên kết HTML với dữ liệu miền rất dễ dàng. Nó thực hiện một mẫu có tên Model-View-ViewModel (MVVM). Observables là thành phần kỳ diệu của KnockoutJS. Tất cả dữ liệu vẫn được đồng bộ hóa do thuộc tính có thể quan sát.

Ngành kiến ​​trúc

Lượt xem

Chế độ xem không là gì ngoài giao diện người dùng được tạo bằng cách sử dụng các phần tử HTML và kiểu CSS.

Bạn có thể liên kết các phần tử DOM HTML với mô hình dữ liệu bằng KnockoutJS. Nó cung cấp liên kết dữ liệu 2 chiều giữa View và ViewModel bằng cách sử dụng khái niệm 'data-bind', có nghĩa là bất kỳ cập nhật nào được thực hiện trong UI đều được phản ánh trong mô hình dữ liệu và mọi thay đổi được thực hiện trong mô hình dữ liệu đều được phản ánh trong UI. Người ta có thể tạo giao diện người dùng tự cập nhật với sự trợ giúp của knockoutJS.

ViewModel

ViewModel là một đối tượng JavaScript, chứa các thuộc tính và chức năng cần thiết để biểu diễn dữ liệu. View và ViewModel được kết nối với nhau bằng khái niệm liên kết dữ liệu khai báo được sử dụng trong HTML. Điều này giúp bạn dễ dàng thay đổi HTML mà không cần thay đổi ViewModel. KnockoutJS chăm sóc dữ liệu tự động làm mới giữa chúng thông qua việc sử dụng Observables.

Đồng bộ hóa dữ liệu đạt được thông qua việc liên kết các phần tử DOM với Mô hình dữ liệu, đầu tiên sử dụng data-bind và sau đó làm mới 2 thành phần này thông qua việc sử dụng Observables. Theo dõi sự phụ thuộc được thực hiện tự động do sự đồng bộ hóa dữ liệu này. Không cần mã hóa thêm để đạt được nó. KnockoutJS cho phép tạo kết nối trực tiếp giữa màn hình và dữ liệu bên dưới.

Bạn có thể tạo ràng buộc của riêng mình được gọi là ràng buộc tùy chỉnh cho các hành vi ứng dụng cụ thể. Bằng cách này, Knockout cho phép kiểm soát trực tiếp cách bạn muốn chuyển đổi dữ liệu của mình thành HTML.

Mô hình

Mô hình là dữ liệu miền trên máy chủ và nó được thao tác khi và khi yêu cầu được gửi / nhận từ ViewModel.

Dữ liệu có thể được lưu trữ trong cơ sở dữ liệu, cookie hoặc hình thức lưu trữ liên tục khác. KnockoutJS không lo lắng về cách nó được lưu trữ. Người lập trình phải giao tiếp giữa dữ liệu được lưu trữ và KnockoutJS.

Hầu hết các lần, dữ liệu được lưu và tải thông qua lệnh gọi Ajax.

Model-View-ViewModel (MVVM)là một mẫu thiết kế kiến ​​trúc để phát triển các ứng dụng phần mềm. MVVM được phát triển bởi Microsoft Architect John Gossman vào năm 2005. Mẫu này có nguồn gốc từ mẫu Model-View-Controller (MVC). Ưu điểm của MVVM là nó tách giao diện người dùng đồ họa của lớp ứng dụng khỏi logic nghiệp vụ. MVVM chịu trách nhiệm xử lý dữ liệu từ mô hình bên dưới theo cách mà nó được đại diện và quản lý rất dễ dàng. ViewModel trong MVVM đại diện cho một phiên bản trừu tượng của trạng thái và hành động của View.

Các lớp xem không biết rằng các lớp Model và ViewModel tồn tại, cũng như Model và ViewModel không biết rằng View tồn tại. Model cũng không biết rằng ViewModel và View tồn tại.

Ngành kiến ​​trúc

Lượt xem

Chế độ xem là Giao diện người dùng đồ họa được tạo bằng ngôn ngữ đánh dấu để biểu diễn dữ liệu. View liên kết với các thuộc tính của ViewModel thông qua khái niệm data-bind, kết nối gián tiếp với dữ liệu mô hình. Không cần thay đổi chế độ xem đối với bất kỳ thay đổi nào được thực hiện trong ViewModel. Các thay đổi được thực hiện đối với dữ liệu trong ViewModel được tự động truyền trong View do ràng buộc.

Mô hình

Mô hình là dữ liệu miền hoặc đối tượng kinh doanh, chứa dữ liệu thời gian thực. Mô hình không thực hiện các hành vi. Hành vi hầu hết được thực hiện trong logic kinh doanh.

ViewModel

ViewModel là nơi trung tâm, nơi dữ liệu từ logic hiển thị của Model và View được nhóm lại với nhau. ViewModel giữ trạng thái động của dữ liệu. Có một chất kết dính ngầm giữa View và ViewModel để giao tiếp với nhau. Liên kết này bao gồm dữ liệu khai báo và ràng buộc lệnh. Đồng bộ hóa View và ViewModel được thực hiện thông qua liên kết này. Bất kỳ thay đổi nào được thực hiện trong View đều được phản ánh trong ViewModel và tương tự, bất kỳ thay đổi nào trong ViewModel sẽ được tự động phản ánh trong View. Sự tồn tại của cơ chế ràng buộc 2 chiều này là một khía cạnh chính của mô hình MVVM này.

KnockoutJS được xây dựng dựa trên 3 khái niệm quan trọng sau đây.

  • Các khả năng quan sát và theo dõi sự phụ thuộc giữa chúng - các phần tử DOM được kết nối với ViewModel thông qua 'data-bind'. Họ trao đổi thông tin thông qua Observables. Điều này tự động xử lý theo dõi phụ thuộc.

  • Liên kết khai báo giữa giao diện người dùng và ViewModel - các phần tử DOM được kết nối với ViewModel thông qua khái niệm 'data-bind'.

  • Tạo khuôn để tạo các thành phần có thể sử dụng lại - Tạo khuôn cung cấp một cách mạnh mẽ để tạo các ứng dụng web phức tạp.

Chúng ta sẽ nghiên cứu về Observables trong chương này.

Như tên chỉ định, khi bạn khai báo dữ liệu / thuộc tính ViewModel là Có thể quan sát, mọi sửa đổi dữ liệu mỗi lần sẽ tự động được phản ánh ở tất cả các vị trí dữ liệu được sử dụng. Điều này cũng bao gồm làm mới các phụ thuộc liên quan. KO đảm nhận những điều này và không cần phải viết thêm mã để đạt được điều này.

Sử dụng Observable, sẽ rất dễ dàng làm cho giao diện người dùng và ViewModel giao tiếp động.

Cú pháp

Bạn chỉ cần khai báo thuộc tính ViewModel với hàm ko.observable() để làm cho nó có thể quan sát được.

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

Thí dụ

Hãy xem ví dụ sau minh họa việc sử dụng 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>

Dòng sau dành cho hộp nhập liệu. Có thể thấy, chúng tôi đã sử dụng thuộc tính data-bind để ràng buộc giá trị yourName với ViewModel.

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

Dòng sau chỉ in giá trị của yourName. Lưu ý rằng ở đây kiểu data-bind là văn bản vì chúng ta chỉ đọc giá trị.

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

Trong dòng sau, ko.observable theo dõi biến yourName để biết bất kỳ sửa đổi nào trong dữ liệu. Sau khi có sửa đổi, các địa điểm tương ứng cũng được cập nhật giá trị đã sửa đổi. Khi bạn chạy mã sau, một hộp nhập liệu sẽ xuất hiện. Như và khi bạn cập nhật hộp nhập đó, giá trị mới sẽ được phản ánh hoặc làm mới ở những nơi mà nó được sử dụng.

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

Đầu ra

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào first_observable_pgm.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Nhập tên là Scott và quan sát rằng tên được phản ánh trong đầu ra.

Việc sửa đổi dữ liệu có thể diễn ra từ giao diện người dùng hoặc từ ViewModel. Bất kể dữ liệu được thay đổi từ đâu, UI và ViewModel vẫn giữ đồng bộ hóa giữa chúng. Điều này làm cho nó trở thành một cơ chế ràng buộc hai chiều. Trong ví dụ trên, khi bạn thay đổi tên của mình trong hộp nhập liệu, ViewModel sẽ nhận được một giá trị mới. Khi bạn thay đổi thuộc tính YourName từ bên trong ViewModel, thì giao diện người dùng sẽ nhận được một giá trị mới.

Đọc và Viết bảng quan sát

Bảng sau liệt kê các thao tác đọc và ghi có thể được thực hiện trên Observables.

Sr.No. Đọc / ghi hoạt động & cú pháp
1

Read

Để đọc giá trị, chỉ cần gọi thuộc tính Observable không có các tham số như: AppViewModel.yourName ();

2

Write

Để ghi / cập nhật giá trị trong thuộc tính Observable, chỉ cần chuyển giá trị mong muốn vào tham số như: AppViewModel.yourName ('Bob');

3

Write multiple

Nhiều thuộc tính ViewModel có thể được cập nhật trong một hàng với sự trợ giúp của cú pháp chuỗi như: AppViewModel.yourName ('Bob'). YourAge (45);

Mảng có thể quan sát

Khai báo có thể quan sát xử lý các sửa đổi dữ liệu của một đối tượng. ObservableArray hoạt động với tập hợp các đối tượng. Đây là một tính năng rất hữu ích khi bạn đang xử lý các ứng dụng phức tạp chứa nhiều loại giá trị và thay đổi trạng thái của chúng thường xuyên dựa trên hành động của người dùng.

Cú pháp

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

Mảng có thể quan sát chỉ theo dõi các đối tượng nào trong đó được thêm vào hoặc loại bỏ. Nó không thông báo nếu các thuộc tính của đối tượng riêng lẻ bị sửa đổi.

Khởi tạo nó lần đầu tiên

Bạn có thể khởi tạo mảng của mình và đồng thời bạn có thể khai báo nó là có thể quan sát được bằng cách chuyển các giá trị ban đầu cho hàm tạo như sau.

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

Đọc từ mảng có thể quan sát

Bạn có thể truy cập các phần tử mảng có thể quan sát như sau.

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

Các hàm ObservableArray

KnockoutJS có tập hợp các hàm mảng có thể quan sát của riêng nó. Chúng thuận tiện vì -

  • Các chức năng này hoạt động trên tất cả các trình duyệt.

  • Các chức năng này sẽ tự động xử lý theo dõi sự phụ thuộc.

  • Cú pháp rất dễ sử dụng. Ví dụ: để chèn một phần tử vào một mảng, bạn chỉ cần sử dụng arrayName.push ('value') thay vì arrayName (). Push ('value').

Sau đây là danh sách các phương thức Mảng quan sát khác nhau.

Sr.No. Phương pháp & Mô tả
1 push ('giá trị')

Chèn một mục mới vào cuối mảng.

2 pop ()

Loại bỏ mục cuối cùng khỏi mảng và trả lại nó.

3 unshift ('giá trị')

Chèn một giá trị mới vào đầu mảng.

4 shift ()

Loại bỏ mục đầu tiên khỏi mảng và trả lại nó.

5 đảo ngược()

Đảo ngược thứ tự của mảng.

6 sắp xếp ()

Sắp xếp các mục mảng theo thứ tự tăng dần.

7 mối nối (chỉ mục đầu, chỉ mục cuối)

Chấp nhận 2 tham số - start-index và end-index - loại bỏ các mục bắt đầu từ chỉ mục đầu đến cuối và trả về chúng dưới dạng một mảng.

số 8 indexOf ('giá trị')

Hàm này trả về chỉ số của lần xuất hiện đầu tiên của tham số được cung cấp.

9 lát (chỉ mục đầu, chỉ mục cuối)

Phương thức này cắt ra một phần của mảng. Trả về các mục từ chỉ mục đầu đến chỉ mục cuối.

10 xóa tất cả()

Loại bỏ tất cả các mục và trả về chúng dưới dạng một mảng.

11 loại bỏ ('giá trị')

Loại bỏ các mục phù hợp với tham số và trả về dưới dạng một mảng.

12 remove (function (item) {condition})

Loại bỏ các mục thỏa mãn điều kiện và trả về chúng dưới dạng một mảng.

13 loại bỏ ([bộ giá trị])

Loại bỏ các mục phù hợp với một bộ giá trị nhất định.

14

destroyAll()

Đánh dấu tất cả các mục trong một mảng có thuộc tính _destroy với giá trị true.

15

destroy('value')

Tìm kiếm một mục bằng tham số và đánh dấu mục đó bằng thuộc tính đặc biệt _destroy với giá trị true.

16

destroy(function(item) { condition})

Tìm tất cả các mục thỏa mãn điều kiện, đánh dấu chúng bằng thuộc tính _destroy với giá trị thực.

17

destroy([set of values])

Tìm các mục phù hợp với một bộ giá trị nhất định, đánh dấu chúng là _destroy với giá trị thực.

Note - Hủy và hủy Tất cả các chức năng từ ObservableArrays hầu hết chỉ dành cho các nhà phát triển 'Ruby on Rails'.

Khi bạn sử dụng phương thức hủy, các mục tương ứng không thực sự bị xóa khỏi mảng tại thời điểm đó nhưng được ẩn bằng cách đánh dấu chúng bằng thuộc tính _destroy có giá trị thực để giao diện người dùng không thể đọc chúng. Các mục được đánh dấu là _destroy bằng true sẽ bị xóa sau đó trong khi xử lý biểu đồ đối tượng JSON.

Computed Observable là một hàm phụ thuộc vào một hoặc nhiều Observables và tự động cập nhật bất cứ khi nào các Observables (phụ thuộc) cơ bản của nó thay đổi.

Các bảng quan sát được tính toán có thể được xâu chuỗi.

Cú pháp

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

Thí dụ

Chúng ta hãy xem ví dụ sau minh họa việc sử dụng 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>

Trong các dòng tiếp theo, hai dòng đầu tiên là để chấp nhận các giá trị đầu vào. Dòng thứ ba in giá trị trung bình của hai số này.

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

Trong các dòng sau, loại Có thể quan sát ablà số khi chúng được khởi tạo lần đầu tiên bên trong ViewModel. Tuy nhiên, trong KO, mọi đầu vào được chấp nhận từ UI theo mặc định ở định dạng Chuỗi. Vì vậy, chúng cần được chuyển đổi thành Số để thực hiện phép toán số học trên chúng.

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);

Trong dòng sau, giá trị trung bình được tính toán được hiển thị trong giao diện người dùng. Lưu ý rằng kiểu liên kết dữ liệu của totalAvg chỉ là văn bản.

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

Đầu ra

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào computed-observable.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Nhập 2 số bất kỳ vào các hộp văn bản và quan sát rằng giá trị trung bình được tính.

Quản lý 'Cái này'

Lưu ý rằng trong ví dụ trên, tham số thứ hai được cung cấp dưới dạng thissang hàm Tính toán. Không thể tham chiếu đến Có thể quan sáta()b() mà không cung cấp this.

Để khắc phục điều này, self biến được sử dụng chứa tham chiếu của this. Làm như vậy, không cần theo dõithistrong suốt mã. Thay thế,self có thể được sử dụng.

Mã ViewModel sau được viết lại cho ví dụ trên bằng cách sử dụng 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;
   });
}

Có thể quan sát được tính toán thuần túy

Một quan sát được tính toán phải được khai báo là PureComputed Observable nếu Observable đó chỉ đơn giản là tính toán và trả về giá trị và không trực tiếp sửa đổi các đối tượng hoặc trạng thái khác. Pure Computed Observables giúp Knockout quản lý việc đánh giá lại và sử dụng bộ nhớ một cách hiệu quả.

Thông báo cho người đăng ký một cách rõ ràng

Khi một Computed Observable trả về giá trị kiểu dữ liệu nguyên thủy (String, Boolean, Null và Number) thì những người đăng ký của nó sẽ được thông báo nếu và chỉ khi sự thay đổi giá trị thực sự diễn ra. Nó có nghĩa là nếu một Observable đã nhận được giá trị giống như giá trị trước đó, thì người đăng ký của nó sẽ không được thông báo.

Bạn có thể làm cho các Đối tượng quan sát được tính toán luôn thông báo rõ ràng cho những người quan sát, ngay cả khi giá trị mới giống với giá trị cũ bằng cách sử dụng notify cú pháp như sau.

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

Giới hạn thông báo thay đổi

Quá nhiều bản cập nhật đắt tiền có thể dẫn đến các vấn đề về hiệu suất. Bạn có thể giới hạn số lượng thông báo nhận được từ Observable bằngrateLimit thuộc tính như sau.

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

Tìm hiểu xem một thuộc tính có thể quan sát được hay không

Trong một số tình huống nhất định, có thể cần phải tìm hiểu xem một thuộc tính có phải là Thuộc tính có thể quan sát được hay không. Các hàm sau đây có thể được sử dụng để xác định các loại có thể quan sát.

Sr.No. Chức năng
1

ko.isComputed

Lợi nhuận true nếu thuộc tính là Computed Observable.

2

ko.isObservable

Lợi nhuận true nếu thuộc tính là mảng có thể quan sát được, có thể quan sát được hoặc có thể quan sát được tính toán.

3

ko.isWritableObservable

Lợi nhuận truenếu mảng có thể quan sát, có thể quan sát được hoặc có thể quan sát được tính toán ghi được. (Cái này còn được gọi là ko.isWritableObservable)

Có thể ghi được tính toán quan sát

Có thể quan sát được tính toán được bắt nguồn từ một hoặc nhiều Có thể quan sát khác, vì vậy nó chỉ được đọc. Tuy nhiên, người ta có thể làm cho Computed Observable có thể ghi được. Đối với điều này, bạn cần cung cấp hàm gọi lại hoạt động trên các giá trị được viết.

Các Observables tính toán có thể ghi này hoạt động giống như các Observables thông thường. Ngoài ra, chúng yêu cầu logic tùy chỉnh được xây dựng để can thiệp vào các hành động đọc và ghi.

Người ta có thể gán giá trị cho nhiều thuộc tính Observables hoặc Computed Observable bằng cách sử dụng cú pháp chuỗi như sau.

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

Thí dụ

Ví dụ sau minh họa việc sử dụng có thể quan sát được có thể tính toán được.

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

Trong đoạn mã trên, rawDate là thuộc tính pureComputed được chấp nhận từ giao diện người dùng. yourAge Có thể quan sát được bắt nguồn từ rawDate.

Ngày trong JavaScript được xử lý bằng mili giây. Do đó, cả ngày (ngày hôm nay và ngày sinh) đều được chuyển đổi thành mili giây và sau đó sự khác biệt giữa chúng được chuyển đổi ngược lại theo năm và tháng.

Đầu ra

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào writable_computed_observable.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Nhập ngày sinh bất kỳ và quan sát rằng tuổi được tính.

Liên kết khai báo trong KnockoutJS cung cấp một cách mạnh mẽ để kết nối dữ liệu với giao diện người dùng.

Điều quan trọng là phải hiểu mối quan hệ giữa các ràng buộc và các Quan sát. Về mặt kỹ thuật, hai cái này khác nhau. Bạn có thể sử dụng đối tượng JavaScript bình thường vì ViewModel và KnockoutJS có thể xử lý ràng buộc của View một cách chính xác.

Nếu không có Observable, thuộc tính từ UI sẽ chỉ được xử lý lần đầu tiên. Trong trường hợp này, nó không thể cập nhật tự động dựa trên bản cập nhật dữ liệu cơ bản. Để đạt được điều này, các ràng buộc phải được tham chiếu đến các thuộc tính Có thể quan sát.

Cú pháp ràng buộc

Đóng gáy gồm 2 mục, ràng buộc namevalue. Sau đây là một ví dụ đơn giản -

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

Ở đây, văn bản là tên liên kết và WhatDay là giá trị liên kết. Bạn có thể có nhiều ràng buộc được phân tách bằng dấu phẩy, như thể hiện trong cú pháp sau.

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

Tại đây, giá trị được cập nhật sau mỗi lần nhấn phím.

Giá trị ràng buộc

Giá trị ràng buộc có thể là một single value, literal, một variable hoặc có thể là một JavaScriptbiểu hiện. Nếu liên kết đề cập đến một số biểu thức hoặc tham chiếu không hợp lệ, thì KO sẽ tạo ra lỗi và ngừng xử lý liên kết.

Sau đây là một số ví dụ về ràng buộc.

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

Lưu ý những điểm sau:

  • Khoảng trắng không tạo ra bất kỳ sự khác biệt nào.

  • Bắt đầu từ KO 3.0, bạn có thể bỏ qua giá trị ràng buộc sẽ cung cấp cho ràng buộc một giá trị không xác định.

Bối cảnh ràng buộc

Dữ liệu đang được sử dụng trong các ràng buộc hiện tại có thể được tham chiếu bởi một đối tượng. Đối tượng này được gọi làbinding context.

Hệ thống phân cấp ngữ cảnh được tạo và quản lý bởi KnockoutJS tự động. Bảng sau liệt kê các loại ngữ cảnh ràng buộc khác nhau do KO cung cấp.

Sr.No. Mô tả và loại ngữ cảnh ràng buộc
1

$root

Điều này luôn đề cập đến ViewModel cấp cao nhất. Điều này giúp bạn có thể truy cập các phương thức cấp cao nhất để thao tác với ViewModel. Đây thường là đối tượng, được chuyển đến ko.applyBindings.

2

$data

Tài sản này rất giống thistừ khóa trong đối tượng Javascript. Thuộc tính $ data trong ngữ cảnh ràng buộc tham chiếu đến đối tượng ViewModel cho ngữ cảnh hiện tại.

3

$index

Thuộc tính này chứa chỉ mục của một mục hiện tại của một mảng bên trong vòng lặp foreach. Giá trị của $ index sẽ tự động thay đổi khi và khi mảng có thể quan sát bên dưới được cập nhật. Rõ ràng, ngữ cảnh này chỉ có sẵn choforeach ràng buộc.

4

$parent

Thuộc tính này tham chiếu đến đối tượng ViewModel mẹ. Điều này rất hữu ích khi bạn muốn truy cập các thuộc tính ViewModel bên ngoài từ bên trong của một vòng lặp lồng nhau.

5

$parentContext

Đối tượng ngữ cảnh được ràng buộc ở cấp cha được gọi là $parentContext. Điều này khác với$parent. $ cha tham chiếu đến dữ liệu. Trong khi, $ parentContext đề cập đến ngữ cảnh ràng buộc. Ví dụ: bạn có thể cần truy cập chỉ mục của mục ngoại cảnh từ ngữ cảnh bên trong.

6

$rawdata

Bối cảnh này giữ giá trị ViewModel thô trong tình huống hiện tại. Điều này giống như$data but the difference is, if ViewModel is wrapped in Observable, then $dữ liệu chỉ trở thành không được gói. ViewModel và $ rawdata trở thành dữ liệu có thể quan sát thực tế.

7

$component

Ngữ cảnh này được sử dụng để chỉ ViewModel của thành phần đó, khi bạn đang ở bên trong một thành phần cụ thể. Ví dụ: bạn có thể muốn truy cập một số thuộc tính từ ViewModel thay vì dữ liệu hiện tại trong phần mẫu của thành phần.

số 8

$componentTemplateNodes

Điều này đại diện cho một mảng các nút DOM được chuyển đến thành phần cụ thể đó khi bạn ở trong một mẫu thành phần cụ thể.

Các điều khoản sau đây cũng có sẵn trong ràng buộc nhưng không thực sự là ngữ cảnh ràng buộc.

  • $context - Đây không là gì ngoài đối tượng ngữ cảnh ràng buộc hiện có.

  • $element - Đối tượng này tham chiếu đến một phần tử trong DOM trong ràng buộc hiện tại.

Làm việc với Văn bản và Hình thức

Sau đây là danh sách các loại ràng buộc do KO cung cấp để xử lý các hình thức văn bản và hình ảnh.

Sr.No. Loại ràng buộc & Cách sử dụng
1 hiển thị:

Để hiển thị hoặc ẩn phần tử DOM HTML tùy thuộc vào các điều kiện nhất định.

2 văn bản:

Để đặt nội dung của một phần tử HTML DOM.

3 html:

Để đặt nội dung đánh dấu HTML của phần tử DOM.

4 css:

Để áp dụng các lớp CSS cho một phần tử.

5 phong cách:

Để xác định thuộc tính kiểu nội tuyến của một phần tử.

6 đính kèm:

Để thêm động các thuộc tính vào một phần tử.

Làm việc với các ràng buộc luồng kiểm soát

Sau đây là danh sách các loại Ràng buộc Luồng Kiểm soát do KO cung cấp.

Sr.No. Loại ràng buộc & Cách sử dụng
1 foreach:

Trong liên kết này, mỗi mục mảng được tham chiếu trong đánh dấu HTML trong một vòng lặp.

2 nếu:

Nếu điều kiện là đúng, thì đánh dấu HTML đã cho sẽ được xử lý. Nếu không, nó sẽ bị xóa khỏi DOM.

3 ifnot:

Phủ định của If. Nếu điều kiện là đúng, thì đánh dấu HTML đã cho sẽ được xử lý. Nếu không, nó sẽ bị xóa khỏi DOM.

4 với:

Liên kết này được sử dụng để liên kết các phần tử con của một đối tượng trong ngữ cảnh của đối tượng được chỉ định.

5 thành phần: HOẶC thành phần:

Liên kết này được sử dụng để chèn một thành phần vào các phần tử DOM và truyền các tham số tùy chọn.

Làm việc với các ràng buộc trường biểu mẫu

Sau đây là danh sách các loại Trường mẫu liên kết do KO cung cấp.

Sr.No. Loại ràng buộc & Cách sử dụng
1 nhấp vào:

Liên kết này được sử dụng để gọi một hàm JavaScript được liên kết với phần tử DOM dựa trên một lần nhấp.

2 sự kiện:

Liên kết này được sử dụng để lắng nghe các sự kiện DOM được chỉ định và gọi các hàm xử lý được liên kết dựa trên chúng.

3 đệ trình:

Liên kết này được sử dụng để gọi một hàm JavaScript khi phần tử DOM được liên kết được gửi.

4 kích hoạt:

Liên kết này được sử dụng để kích hoạt các phần tử DOM nhất định dựa trên một điều kiện cụ thể.

5 vô hiệu hóa:

Liên kết này vô hiệu hóa phần tử DOM được liên kết khi tham số đánh giá là true.

6 giá trị:

Liên kết này được sử dụng để liên kết giá trị của phần tử DOM tương ứng với thuộc tính ViewModel.

7 textInput:

Liên kết này được sử dụng để tạo liên kết 2 chiều giữa hộp văn bản hoặc vùng văn bản và thuộc tính ViewModel.

số 8 hasFocus:

Liên kết này được sử dụng để đặt tiêu điểm của phần tử HTML DOM theo cách thủ công thông qua thuộc tính ViewModel.

9 đã kiểm tra:

Liên kết này được sử dụng để tạo liên kết giữa phần tử biểu mẫu có thể kiểm tra và thuộc tính ViewModel.

10 tùy chọn:

Liên kết này được sử dụng để xác định các tùy chọn cho một phần tử được chọn.

11 selectOptions:

Liên kết này được sử dụng để làm việc với các phần tử đang được chọn trong điều khiển biểu mẫu chọn nhiều danh sách.

12 uniqueName:

Liên kết này được sử dụng để tạo tên duy nhất cho phần tử DOM.

KnockoutJs tự động theo dõi các phụ thuộc khi các giá trị được cập nhật. Nó có một đối tượng duy nhất được gọi làdependency tracker (ko.dependencyDetection) hoạt động như một trung gian giữa hai bên để đăng ký các phụ thuộc.

Sau đây là thuật toán để theo dõi sự phụ thuộc.

Step 1 - Bất cứ khi nào bạn khai báo một hàm quan sát được tính toán, KO ngay lập tức gọi hàm đánh giá của nó để lấy giá trị ban đầu của nó.

Step 2- Đăng ký được thiết lập cho bất kỳ người đánh giá nào có thể quan sát được. Trong một ứng dụng, các đăng ký cũ không còn được sử dụng sẽ được xử lý.

Step 3 - KO cuối cùng thông báo cập nhật tính toán quan sát được.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào dependency_tracking.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Nhập tên trái cây bất kỳ và nhấp vào nút Thêm.

Kiểm soát sự phụ thuộc bằng cách sử dụng Peek

Computed Observable có thể được truy cập mà không cần tạo ra sự phụ thuộc, bằng cách sử dụng peekchức năng. Nó điều khiển Observable bằng cách cập nhật thuộc tính được tính toán.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào dependency_tracking_peek.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

Quan sát

Bỏ qua phụ thuộc trong phụ thuộc được tính

Các ko.ignoreDependencieshàm giúp bỏ qua những phụ thuộc mà bạn không muốn theo dõi trong các phụ thuộc được tính toán. Sau đây là cú pháp của nó.

ko.ignoreDependencies( callback, callbackTarget, callbackArgs );

Tại sao sự phụ thuộc vòng tròn không có ý nghĩa

Nếu KO đang đánh giá một Có thể quan sát được tính toán, thì nó sẽ không bắt đầu lại đánh giá Đối tượng có thể quan sát được tính toán phụ thuộc. Do đó, không có ý nghĩa gì khi bao gồm các chu kỳ trong chuỗi phụ thuộc của bạn.

Templatelà một tập hợp các phần tử DOM có thể được sử dụng lặp đi lặp lại. Templating giúp dễ dàng xây dựng các ứng dụng phức tạp do đặc tính của nó là giảm thiểu sự trùng lặp của các phần tử DOM.

Có 2 cách tạo mẫu.

  • Native templating- Phương pháp này hỗ trợ các ràng buộc luồng điều khiển như foreach, with và if. Các liên kết này nắm bắt đánh dấu HTML hiện có trong phần tử và sử dụng nó làm mẫu cho các mục ngẫu nhiên. Không cần thư viện bên ngoài cho việc tạo khuôn mẫu này.

  • String-based templating- KO kết nối với công cụ của bên thứ ba để chuyển các giá trị ViewModel vào đó và đưa đánh dấu kết quả vào tài liệu. Ví dụ: JQuery.tmpl và Underscore Engine.

Syntax

template: <parameter-value>

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

Lưu ý rằng type được cung cấp như text/html trong khối script để thông báo cho KO rằng, nó không phải là một khối thực thi mà chỉ là một khối mẫu cần được hiển thị.

Parameters

Sự kết hợp của các thuộc tính sau đây có thể được gửi dưới dạng tham số-giá trị cho mẫu.

  • name - Điều này thể hiện tên của mẫu.

  • nodes- Điều này đại diện cho một mảng các nút DOM được sử dụng làm mẫu. Tham số này bị bỏ qua nếu tham số tên được truyền.

  • data - Đây không là gì ngoài dữ liệu được hiển thị qua mẫu.

  • if - Mẫu sẽ được phân phát nếu điều kiện đã cho dẫn đến giá trị true hoặc giống true.

  • foreach - Để cung cấp mẫu ở định dạng foreach.

  • as - Đây chỉ là để tạo một bí danh trong phần tử foreach.

  • afterAdd, afterRender, beforeRemove - Đây là tất cả để đại diện cho các hàm có thể gọi được thực thi tùy thuộc vào hoạt động được thực hiện.

Quan sát

Hiển thị một Mẫu được đặt tên

Các mẫu được định nghĩa ngầm định bằng đánh dấu HTML bên trong DOM khi được sử dụng với các ràng buộc luồng điều khiển. Tuy nhiên, nếu bạn muốn, bạn có thể chia các mẫu thành một phần tử riêng biệt và sau đó tham chiếu chúng theo tên.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào template-named.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Ở đây, friend-template được sử dụng 2 lần.

Sử dụng "foreach" trong Mẫu

Sau đây là một ví dụ về việc sử dụng foreach cùng với tên mẫu.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào template-foreach.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Ở đây, điều khiển foreach được sử dụng trong liên kết mẫu.

Tạo bí danh Sử dụng làm Từ khóa cho các Mục foreach

Sau đây là cách có thể tạo bí danh cho một mục foreach:

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

Dễ dàng tham chiếu đến các đối tượng cha từ bên trong vòng lặp foreach bằng cách tạo bí danh. Tính năng này hữu ích khi mã phức tạp và được lồng ở nhiều cấp.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào template-as-alias.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Bí danh được sử dụng thay cho tên đầy đủ của mảng.

Sử dụng afterAdd, beforeRemove và afterRender

Có những tình huống trong đó logic tùy chỉnh bổ sung cần được chạy trên các phần tử DOM được tạo bởi mẫu. Trong trường hợp này, có thể sử dụng các lệnh gọi lại sau. Hãy xem xét rằng bạn đang sử dụng phần tử foreach sau đó -

afterAdd - Hàm này được gọi khi một mục mới được thêm vào mảng được đề cập trong foreach.

beforeRemove - Hàm này được gọi ngay trước khi xóa mục khỏi mảng được đề cập trong foreach.

afterRender - Hàm được đề cập ở đây được gọi mỗi khi foreach được hiển thị và các mục mới được thêm vào mảng.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào template-afterrender.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Ở đây, hàm afterProcess được thực thi mỗi khi foreach được hiển thị.

Chọn mẫu động

Nếu có sẵn nhiều mẫu, thì một mẫu có thể được chọn động bằng cách đặt tên là observabletham số. Do đó, giá trị mẫu sẽ được đánh giá lại khi tham số tên thay đổi và đến lượt dữ liệu sẽ được hiển thị lại.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào template-dynamic.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

  • Mẫu được sử dụng được quyết định tùy thuộc vào giá trị cờ hoạt động.

Sử dụng công cụ dựa trên chuỗi bên ngoài

Native templating hoạt động hoàn hảo với các phần tử luồng điều khiển khác nhau ngay cả với các khối mã lồng nhau. KO cũng cung cấp một cách để tích hợp với thư viện tạo khuôn mẫu bên ngoài chẳng hạn như Công cụ tạo khuôn mẫu dưới điểm nhấn hoặc JQuery.tmpl.

Như đã đề cập trên trang web chính thức JQuery.tmpl không còn được phát triển tích cực kể từ tháng 12 năm 2011. Do đó, khuôn mẫu gốc của KO chỉ được khuyến nghị thay vì JQuery.tmpl hoặc bất kỳ công cụ mẫu dựa trên chuỗi nào khác.

Vui lòng tham khảo trang web chính thức để biết thêm chi tiết về điều này.

Các thành phần là một cách rất lớn để tổ chức mã giao diện người dùng để cấu trúc một ứng dụng lớn và thúc đẩy khả năng tái sử dụng mã.

Nó được kế thừa hoặc lồng ghép từ thành phần khác. Để tải và cấu hình, nó xác định các quy ước hoặc logic của riêng nó.

Nó được đóng gói để sử dụng lại trong toàn bộ ứng dụng hoặc dự án. Trình bày các phần hoàn chỉnh của ứng dụng hoặc các điều khiển / tiện ích nhỏ. Nó có thể được tải hoặc tải trước theo yêu cầu.

Đăng ký thành phần

Các thành phần có thể đăng ký bằng cách sử dụng ko.components.register()API. Nó giúp tải và biểu diễn các thành phần trong KO. Tên thành phần với cấu hình được mong đợi để đăng ký. Cấu hình chỉ định cách xác định viewModel và mẫu.

Syntax

Các thành phần có thể được đăng ký như sau:

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • Các component-name có thể là bất kỳ chuỗi trống nào.

  • viewModel là tùy chọn và có thể sử dụng bất kỳ định dạng viewModel nào được liệt kê trong các phần tiếp theo.

  • template là bắt buộc và có thể sử dụng bất kỳ định dạng mẫu nào được liệt kê trong các phần tiếp theo.

Nêu một ViewModel

Bảng sau liệt kê các định dạng viewModel có thể được sử dụng để đăng ký các thành phần.

Sr.No. viewModel Forms & Description
1

constructor function

Nó tạo một đối tượng viewModel riêng biệt cho từng thành phần. Đối tượng hoặc chức năng được sử dụng để liên kết trong chế độ xem thành phần.

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

shared object instance

Cá thể đối tượng viewModel được chia sẻ. Thuộc tính instance được chuyển để sử dụng đối tượng trực tiếp.

var sharedViewModelInstance = { ... };

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

createViewModel

Nó gọi một hàm hoạt động như một nhà máy và có thể được sử dụng như một mô hình khung nhìn có thể trả về một đối tượng.

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

AMD module

Nó là một định dạng mô-đun để xác định các mô-đun trong đó mô-đun và các phần phụ thuộc đều được tải không đồng bộ.

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

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

   return MyViewModel;
});

Nêu mẫu

Bảng sau liệt kê các định dạng mẫu có thể được sử dụng để đăng ký các thành phần.

Sr.No. Biểu mẫu
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: ...
});

Các thành phần được đăng ký dưới dạng một mô-đun AMD duy nhất

Mô-đun AMD có thể tự đăng ký một thành phần mà không cần sử dụng cặp viewModel / template.

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

Ràng buộc thành phần

Có hai cách liên kết thành phần.

  • Full syntax- Nó truyền tham số và đối tượng cho thành phần. Nó có thể vượt qua bằng cách sử dụng các thuộc tính sau.

    • name - Nó thêm tên thành phần.

    • params - Nó có thể truyền nhiều tham số trong đối tượng trên thành phần.

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax - Nó chuyển chuỗi dưới dạng tên thành phần và nó không bao gồm tham số trong đó.

<div data-bind = 'component: "component name"'></div>
  • Template-only components - Các thành phần chỉ có thể xác định mẫu mà không chỉ định viewModel.

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element- Các thành phần có thể được sử dụng mà không cần sử dụng thêm phần tử thùng chứa. Điều này có thể được thực hiện bằng cách sử dụngcontainerless flow điều khiển tương tự như thẻ nhận xét.

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

Yếu tố tùy chỉnh

Phần tử tùy chỉnh là một cách để hiển thị một thành phần. Tại đây, bạn có thể viết trực tiếp tên phần tử đánh dấu tự mô tả thay vì xác định trình giữ chỗ, nơi các thành phần được liên kết thông qua nó.

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

Thông số vượt qua

paramsthuộc tính được sử dụng để truyền tham số cho thành phần viewModel. Nó tương tự như thuộc tính data-bind. Nội dung của thuộc tính params được hiểu giống như một đối tượng JavaScript theo nghĩa đen (giống như thuộc tính data-bind), vì vậy bạn có thể chuyển các giá trị tùy ý thuộc bất kỳ loại nào. Nó có thể truyền tham số theo những cách sau:

  • Communication between parent and child components- Thành phần không được khởi tạo bởi chính nó, do đó các thuộc tính của khung nhìn được tham chiếu từ bên ngoài thành phần và do đó sẽ được nhận bởi khung nhìn thành phần con. Ví dụ: bạn có thể thấy trong cú pháp sauModelValue là khung nhìn mẹ, được nhận bởi hàm tạo viewModel con ModelProperty.

  • Passing observable expressions - Nó có ba giá trị trong tham số params.

    • simpleExpression- Nó là một giá trị số. Nó không liên quan đến bất kỳ vật thể quan sát nào.

    • simpleObservable- Nó là một thể hiện được định nghĩa trên viewModel cha. ViewModel mẹ sẽ tự động nhận các thay đổi trên viewModel con có thể quan sát được.

    • observableExpression- Biểu thức đọc có thể quan sát được khi biểu thức được đánh giá bởi chính nó. Khi giá trị quan sát được thay đổi, thì kết quả của biểu thức cũng có thể thay đổi theo thời gian.

Chúng ta có thể chuyển các tham số như sau:

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

Chúng ta có thể chuyển các tham số trong viewModel như sau:

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

Chuyển đánh dấu vào các thành phần

Đánh dấu nhận được được sử dụng để tạo một thành phần và được chọn làm một phần của đầu ra. Các nút sau được chuyển như một phần của đầu ra trong mẫu thành phần.

template: { nodes: $componentTemplateNodes }

Kiểm soát tên thẻ phần tử tùy chỉnh

Tên mà bạn đăng ký trong các thành phần sử dụng ko.components.register, cùng một tên tương ứng với tên thẻ phần tử tùy chỉnh. Chúng tôi có thể thay đổi tên thẻ phần tử tùy chỉnh bằng cách ghi đè nó để kiểm soát bằng cách sử dụnggetComponentNameForNode.

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

Đăng ký các phần tử tùy chỉnh

Các phần tử tùy chỉnh có thể được cung cấp ngay lập tức, nếu trình tải thành phần mặc định được sử dụng và do đó thành phần được đăng ký bằng ko.components.register. Nếu chúng tôi không sử dụngko.components.registervà triển khai trình tải thành phần tùy chỉnh, sau đó phần tử tùy chỉnh có thể được sử dụng bằng cách xác định bất kỳ tên phần tử nào được lựa chọn. Không cần chỉ định cấu hình khi bạn đang sử dụngko.components.register vì trình tải thành phần tùy chỉnh không sử dụng nó nữa.

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

Hãy thực hiện các bước sau để xem mã trên hoạt động như thế nào -

  • Lưu mã trên vào component_register.htm tập tin.

  • Mở tệp HTML này trong trình duyệt.

Máy xúc thành phần

Bộ tải thành phần được sử dụng để truyền không đồng bộ cặp template / viewModel cho tên thành phần đã cho.

Trình tải thành phần mặc định

Bộ tải thành phần mặc định phụ thuộc vào cấu hình được đăng ký rõ ràng. Mỗi thành phần được đăng ký trước khi sử dụng thành phần.

ko.components.defaultLoader

Chức năng tiện ích của trình tải thành phần

Bộ nạp thành phần mặc định có thể đọc và ghi bằng các chức năng sau.

Sr.No. Chức năng tiện ích & Mô tả
1

ko.components.register(name, configuration)

Thành phần đã được đăng ký.

2

ko.components.isRegistered(name)

Nếu tên thành phần cụ thể đã được đăng ký, thì nó sẽ trả về là true, ngược lại là false.

3

ko.components.unregister(name)

Tên thành phần bị xóa khỏi sổ đăng ký.

4

ko.components.get(name, callback)

Chức năng này lần lượt đến từng bộ tải đã đăng ký để tìm ai đã vượt qua định nghĩa viewModel / template cho tên thành phần như trước. Sau đó, nó trả về khai báo viewModel / template bằng cách gọicallback. Nếu trình tải đã đăng ký không thể tìm thấy bất kỳ điều gì về thành phần, thì nó sẽ gọicallback(null).

5

ko.components.clearCachedDefinition(name)

Hàm này có thể được gọi khi chúng ta muốn xóa mục nhập bộ nhớ cache thành phần đã cho. Nếu thành phần cần thiết vào lần sau, một lần nữa người nạp sẽ được tham khảo ý kiến.

Triển khai trình tải thành phần tùy chỉnh

Trình tải thành phần tùy chỉnh có thể được triển khai theo những cách sau:

  • getConfig(name, callback)- Tùy thuộc vào các tên, chúng ta có thể chuyển các cấu hình theo chương trình. Chúng ta có thể gọi callback (componentConfig) để chuyển các cấu hình, trong đó đối tượng componentConfig có thể được loadComponent hoặc bất kỳ trình nạp nào khác sử dụng.

  • loadComponent(name, componentConfig, callback)- Chức năng này giải quyết viewModel và phần mẫu của cấu hình tùy thuộc vào cách nó được cấu hình. Chúng ta có thể gọi callback (kết quả) để chuyển cặp viewmodel / template, trong đó kết quả đối tượng được xác định bởi các thuộc tính sau.

    • template- Bắt buộc. Trả về mảng các nút DOM.

    • createViewModel(params, componentInfo)- Không bắt buộc. Trả về đối tượng viewModel tùy thuộc vào cách cấu hình thuộc tính viewModel.

  • loadTemplate(name, templateConfig, callback)- Các nút DOM được chuyển vào một mẫu bằng cách sử dụng logic tùy chỉnh. Đối tượng templateConfig là một thuộc tính của mẫu từ một object componentConfig. callback (domNodeArray) được gọi để chuyển một mảng các nút DOM.

  • loadViewModel(name, templateConfig, callback) - nhà máy viewModel được chuyển vào cấu hình viewModel bằng cách sử dụng logic tùy chỉnh.