2013-02-14 41 views
18

Tôi có một chút javascript:KnockoutJS giá trị toggling trong dữ liệu ràng buộc

function ViewModel() { 
    var self = this; 
    self.highlight = ko.observable(true); 
} 

ko.applyBindings(new ViewModel()); 

Và html bổ sung cho nó:

<div data-bind="css: { highlighted: highlight }, click: highlight(!highlight())"> 
    random string 
</div> 

Những gì tôi đang cố gắng để đạt được:

  1. Lớp css 'được đánh dấu' chỉ được kích hoạt khi đánh dấu var là đúng
  2. Nhấp vào div sẽ chuyển giá trị bool của var nổi bật
  3. kết quả Wanted: nhấp vào div để kích hoạt/tắt lớp css của nó

gì tôi nhận được:

  1. Giá trị ban đầu của nổi bật là true, nhưng lớp css bắt đầu bị hủy kích hoạt (nếu tôi thay đổi giá trị ban đầu thành false, lớp css được kích hoạt: có vẻ như tôi đã kích hoạt nhấp chuột nào đó khi tôi chưa nhấp vào bất kỳ thứ gì)
  2. lớp css của div không bật nhấp vào

Tôi không muốn tạo hàm nhấp chuột tương ứng mới trong ViewModel. Tôi đang tìm kiếm nếu có thể cho một chút mã tôi có thể đặt chỉ nội tuyến trong các ràng buộc dữ liệu.

Dưới đây là các mã trên JSFiddle: http://jsfiddle.net/4wt4x/1/

bất cứ ai có thể giải thích những gì đang xảy ra và những gì tôi đang làm sai?

Trả lời

19

click: highlight(!highlight()) của bạn không chính xác. Nhấp vào sẽ cố gắng thực hiện một hàm và khi liên kết được khởi tạo, đánh dấu sẽ trả về bất kỳ giá trị nào của nó và đó là nhấp chuột sẽ cố gắng thực hiện (true hoặc false trong trường hợp của bạn). Bạn cần phải làm một cái gì đó như thế này:

Trong javascript của bạn, diễn ra trong mô hình của bạn:

self.toggleHighlight = function() { self.highlight(!self.highlight()) }; 

Sau đó thay đổi các ràng buộc để nói click: toggleHighlight

Giống như vậy: http://jsfiddle.net/KDypD/1/

Bạn có thể cần để điều chỉnh giá trị ban đầu nổi bật của bạn để phản ánh cách bạn muốn trang hiển thị ban đầu.

+0

Cảm ơn bạn đã trả lời. Có cách nào để làm điều này một mình trong bản thân ràng buộc dữ liệu không? Đó là những gì tôi đang tìm kiếm nếu có thể. – dk123

+1

Cá nhân tôi sẽ xem xét việc thực hành không tốt để đặt một cái gì đó như thế trong một ràng buộc. Toàn bộ vấn đề là giữ cho chế độ xem của bạn tách biệt với javascript của bạn. Tuy nhiên, nếu bạn thực sự muốn nó như thế, bạn có thể chỉ cần nhấp vào: function (self) {self.highlight (! Self.highlight())} cho ràng buộc, nhưng tôi sẽ không khuyên rằng kể từ khi gỡ lỗi sau này bạn sẽ kết thúc phải tìm javascript ở hai nơi thay vì chỉ một. Nó trở thành một vấn đề với các dự án lớn hơn với nhiều người đóng góp. –

+0

Cảm ơn bạn đã trả lời và nhận xét thêm về cấu trúc khung nhìn. Tôi sẽ đi với ý tưởng của bạn và tạo ra các chức năng trong javascript. Cảm ơn! – dk123

38

Tôi biết đó là một câu hỏi cũ, nhưng có thể có thể giúp ai đó. Nếu bạn cần phải sử dụng chuyển đổi trong rất nhiều nơi, có thể một số đường tùy chỉnh ràng buộc có thể giúp bạn:

Binding:

ko.bindingHandlers.toggleClick = { 
    init: function (element, valueAccessor) { 
     var value = valueAccessor(); 

     ko.utils.registerEventHandler(element, "click", function() { 
      value(!value()); 
     }); 
    } 
}; 

Cách sử dụng:

<div data-bind="css: { highlighted: highlight }, toggleClick: highlight"> 
    random string 
</div> 

Ví dụ :

http://jsfiddle.net/A28UD/1/

Cách tiếp cận này giữ cho một số chế độ xem của tôi trở nên rõ ràng hơn. Hy vọng nó giúp.

+2

Đây phải là IMO trả lời được chấp nhận. – MattSizzle

+1

ko.utils.registerEventHandler +1 – Moon

+0

Đó chính xác là những gì tôi đang tìm kiếm – Koscik

4

Nếu bạn thực sự muốn làm điều đó inline:

<div data-bind="click: highlight.bind($root, !highlight()), css: { highlighted: highlight } "> 
    random string 
</div> 

nơi nổi bật là boolean thể quan sát được.

6

Một lựa chọn khác là sử dụng một phần mở rộng chức năng tùy chỉnh tái sử dụng (chức năng tùy chỉnh được sử dụng thay vì mở rộng bởi vì không có thông số và có vẻ sạch hơn):

ko.observable.fn.toggleable = function() { 
    var self = this; 
    self.toggle = function() { 
     self(!self()); 
    }; 

    return self; 
}; 

Cách sử dụng

self.highlight = ko.observable(true).toggleable(); 

Html

<div data-bind="css: { highlighted: highlight }, click: highlight.toggle"> 
    random string 
</div> 
+0

Tôi thích phương pháp này vì bạn có thể sử dụng chức năng 'toggle' trong bất kỳ loại sự kiện nào, hoặc thậm chí trong mã. – Grinn

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