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

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.