2012-12-19 36 views
5

Tôi có một kiểu xem phải được gắn vào một sự kiện nhấp chuột của một thẻ <li>. Dưới đây là viewmodel và đánh dấuRàng buộc loại bỏ không xác định cho nhấp chuột

var viewModel = 
    { 
     Folders: ['Inbox', 'Archive', 'Sent', 'Spam'], 
     SelectedFolder: ko.observable('Inbox'), 
     chosenFolderId: ko.observable(), 
     navigate: function() { 
      self.chosenFolderId(folder);    
     } 
    }; 
ko.applyBindings(viewModel); 

Và đánh dấu là

<ul class="nav nav-list bs-docs-sidenav affix" data-bind="foreach:Folders"> 
       @*<li data-bind="css:{active: $data == chosenFolderId() }">*@ 
       <li> 
        <a href="#" data-bind="click:navigate">      
         <!-- ko text: $data --> 
         <!-- /ko --> 
         <i class="icon-chevron-right"></i> 
        </a> 
       </li>     
      </ul> 

Vấn đề là ở dòng này

<a href="#" data-bind="click:navigate"> 

<li data-bind="css:{active: $data == chosenFolderId() }"> 

Cả Dòng trên là không được gắn vàoChức năngvà chosenFolderId có thể quan sát tương ứng. Nó nói rằng Navigate là không xác định. Không thể phân tích cú pháp này . Same goes for selectedFolderId`.

Bất kỳ ý tưởng nào về việc nó xảy ra?

Trả lời

10

Bạn có một vài vấn đề với cách tiếp cận hiện tại của bạn:

Khi bạn sử dụng một ví dụ foreach bindingdata-bind="foreach:Folders" bên ul sự "bối cảnh currect" sẽ là các mục của bạn trong bộ sưu tập thư mục của bạn.

Vì vậy, nếu bạn muốn truy cập vào navigate hay chosenFolderId phương pháp bạn cần phải sử dụng $parent, hoặc $root để truy cập của bạn "root" viewmodel (bạn có thể đọc thêm về binding context):

<ul class="nav nav-list bs-docs-sidenav affix" data-bind="foreach:Folders"> 
    <li data-bind="css:{active: $data == $parent.chosenFolderId() }"> 
     <a href="#" data-bind="click: $parent.navigate">      
      <!-- ko text: $data --> 
      <!-- /ko --> 
      <i class="icon-chevron-right"></i> 
     </a> 
    </li>     
</ul>​ 

Bạn cũng có một số vấn đề trong mô hình xem của bạn. Nếu quý vị có chức năng phức tạp như navigate mà cố gắng sử dụng self bạn nên sử dụng một chức năng như một viewmodel thay vì một đối tượng theo nghĩa đen, nơi bạn có thể lưu trữ this:

var viewModel = function() { 
    var self = this; 
    self.Folders = ['Inbox', 'Archive', 'Sent', 'Spam']; 
    self.SelectedFolder = ko.observable('Inbox'); 
    self.chosenFolderId = ko.observable(); 
    self.navigate = function(folder) { 
     self.chosenFolderId(folder); 
    } 
}; 
ko.applyBindings(new viewModel());​ 

Lưu ý rằng: chức năng navigate của bạn cần một tham số folder để làm nó hoạt động và Knockout sẽ chuyển mục hiện tại cho bạn.

Đây là working JSFiddle.

Nếu bạn muốn làm điều đó với một đối tượng theo nghĩa đen như mô hình xem của bạn ở đây là JSFiddle, minh họa cách tiếp cận đó.

Tuy nhiên, bạn nên biết sức mạnh và độ tuần của phương pháp tạo mô hình hai chế độ xem là gì. Câu hỏi SO này tóm tắt tốt: Difference between knockout View Models declared as object literals vs functions

+0

Vâng tôi đã làm điều đó với cách tiếp cận này. Nhưng tôi muốn nó làm với mô hình mô-đun thay vì chỉ đẩy các ràng buộc thông qua các chức năng. Vì vậy, với cách tiếp cận của bạn hoàn toàn hợp lệ. Tôi không thể làm tương tự với cách tiếp cận của tôi? – Joy

+0

@Joy Tôi không thực sự theo dõi bạn ... bạn có thể tổ chức chức năng tạo mô hình chế độ xem của bạn với mẫu mô-đun. Bạn có thể cập nhật jsfiddle của tôi với mã bạn tưởng tượng không? – nemesv

+0

@Joy Có một vài cách để làm cho nó hoạt động với các đối tượng literals như thế này: http://jsfiddle.net/8Y5cv/1/. Nhưng cuối cùng bạn sẽ gặp phải một số trường hợp mà nó sẽ không đủ cho nhu cầu của bạn. – nemesv

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