2012-12-20 44 views
5

Tôi đang sử dụng KnockoutJS và cố gắng đăng ký một số observable có trong số observableArray có trong số observableArray. Vì vậy, ViewModel của tôi trông như thế này ...Cách đăng ký để quan sát được tại observableArray

function viewModel() { 
    // private properties 
    var self = this; 

    // public properties 
    self.movies = ko.mapping.fromJS([]); 

    // subscriptions 
    self.movies.UserMovies.Rating.subscribe(function(newValue) { 
     console.log(newValue); 
    }); 
} 

Các movies observableArray sẽ trông như thế này một lần dân cư từ các plugin lập bản đồ ...

[{ 
    Id: 1, 
    Title: 'Movie1', 
    Year: 2010, 
    UserMovies: [{ Id: 11, Rating: 3.5, IsWatched: true }] 
},{ 
    Id: 2, 
    Title: 'Movie2', 
    Year: 2010, 
    UserMovies: [{ Id: 4, Rating: 4, IsWatched: true }] 
}] 

Tôi đang cố gắng để thiết lập một thuê bao UserMovies .Rating nhưng, từ ViewModel trên tôi nhận được thông báo lỗi

TypeError: self.movies.UserMovies is undefined

Làm thế nào tôi sẽ nhận được về việc thiết lập một thuê bao để UserMovies.Rating khi nó được điền từ plugin bản đồ?

+0

Bạn có thể sử dụng phiên bản mới nhất của plugin này nếu bạn muốn đăng ký sâu vào mảng: https://github.com/ZiadJ/knockoutjs-reactor – Ziad

Trả lời

7

Loại bỏ không cung cấp mức độ chi tiết để biết các mục nào đã thay đổi trong một mảng, chỉ cần thay đổi điều gì đó. Bạn sẽ cần phải lặp lại máng mảng mỗi khi một mục được thêm vào hoặc bị loại bỏ.

Các foreach ràng buộc (qua ko.utils.compareArrays) thực sự tính toán số lượng hoạt động tối thiểu để chuyển đổi một mảng thành một mảng khác, sao cho các phần tử DOM không cần phải được tạo lại.

Sử dụng ko.utils.compareArrays, tôi có thể tạo phương thức đăng ký thay đổi mảng ở cấp mục. Tận dụng điều này, tôi có thể viết phương thức select quản lý đăng ký.

http://jsfiddle.net/MizardX/s9M4z/

Với phương pháp mới select, bạn có thể làm được điều này khá ngắn gọn:

// Subscribe to items added to the array. The returned 'subscription' will be 
// disposed of, when the item is later removed. 
viewModel.movies.select(function (movie) { 

    // Return the subscription. Same as above. 
    return movie.UserMovies.select(function (userMovie) { 

     // Subscribe to a non-array. The callback will receive the updated value, 
     // instead of the an added item. 
     return userMovie.Rating.select(function (rating) { 

      // Executed each time a rating is updated. 
      console.log(movie.Id(), userMovie.Id(), rating); 
     }); 
    }); 
}); 

Nó xử lý bổ sung, cập nhật và xóa như mong đợi.

+0

Đây là câu trả lời hay. Cảm ơn bạn Markus :) – bflemi3

+0

@ bflemi3 Tôi đã không hài lòng với phiên bản trước, vì nó không thể xử lý xóa. Cái này mạnh mẽ hơn. –

2

Tôi nghĩ rằng bạn sẽ phải lặp qua phim của bạn và đăng ký tài sản giá của mỗi người:

$.each(self.movies(), function(i, movie) { 
    movie.Rating.subscribe(function(newRatingValue){ /* ... */ }) 
}); 

Tất nhiên donwside ở đây là bạn cũng sẽ phải đăng ký vào các mảng chính nó, cho các tình huống mà bạn thêm phim mới vào mảng và sau đó đăng ký theo cách thủ công các thay đổi trong giá trị xếp hạng của chúng.

0

Bạn có thể loại đăng ký tài sản của bạn theo cách này:

var UserMovies = function (data) { 
     this.Id = ko.observable(); 
     this.Rating = ko.observable(); 
     this.IsWatched = ko.observable(); 
     this.update(data); 
    } 

    ko.utils.extend(UserMovies.prototype, { 
     update: function (data) { 
      this.Id(data.Id || ""); 
      this.Rating(data.Rating || ""); 
      this.Rating.subscribe(function (newValue) { 
       console.log(newValue); 
      }); 
      this.IsWatched(data.IsWatched || ""); 
     } 
    }); 

Tôi không chắc chắn những gì bạn có thể làm hoặc không làm từ đăng ký vào những thứ bên trong của đối tượng của bạn, nhưng điều này không công việc. Tôi cũng không chắc liệu mỗi đăng ký sẽ là duy nhất hay nếu một thay đổi Xếp hạng sẽ tắt tất cả các đăng ký xếp hạng UserMovies. Tôi chưa thử nghiệm điều đó. Tôi đã chỉ sử dụng điều này trong các đối tượng duy nhất và không phải mảng các đối tượng.

Các vấn đề liên quan