2013-05-05 28 views
7

Tôi đang sử dụng jquery quicksearch để tìm kiếm một bảng đang được phổ biến bởi vòng lặp forout loại bỏ. yếu tố tìm kiếm nhanh cần phải bắt đầu sau khi kết thúc foreach. Tôi đã thử một số cách tiếp cận, nhưng đã không thành công cho đến nay.knockout - thực thi mã sau khi mục cuối cùng đã được trả lại

Tôi đã thử sử dụng 'afterRender', nhưng không thể xác định xem mục hiện tại là mục cuối cùng trên bộ sưu tập, tôi cũng đã thử sử dụng bindingHandlers, nhưng sau đó tôi nhận được bộ sưu tập có độ dài 0 thay thế chiều dài 2005.

vậy:

  1. phương pháp tốt nhất để tìm kiếm các yếu tố cuối cùng trong một vòng lặp foreach là gì?
  2. cách tốt nhất để triển khai nó trong trường hợp cụ thể này là gì?

đây là quan điểm của tôi:

<tbody data-bind="foreach: containers"> 
     <tr> 
      <td><span data-bind="text: code"></span></td> 
      <td><span data-bind="text: typeName"></span></td> 
      <td><span data-bind="text: parentClient"></span></td> 
      <td><span data-bind="text: client"></span></td> 
      <td> 
       <a data-bind="attr: { onclick: deleteUrl }"> 
        <i class="icon-trash"></i>@delete </a> 
       | 
       <a data-bind="attr: { href: editUrl }"> 
        <i class="icon-edit"></i>@edit</a> 
       | 
       <a data-bind="attr: { href: qrUrl }" target="blank"> 
        <i class="icon-qrcode"></i> 
        @printQr 
       </a> 
      </td> 

     </tr> 
    </tbody> 

và đây là mã loại trực tiếp của tôi:

function Container(data) { 
     var self = this; 
     self.id = ko.observable(data.Id); 
     self.code = ko.observable(data.Code); 
     self.typeName = ko.observable(data.TypeName); 
     self.parentClient = ko.observable(data.ParentClient); 
     self.client = ko.observable(data.Client); 
     self.deleteUrl = ko.computed(function() { 
      return "GetModal('/Containers/Delete/" + data.Id + "','containerModal');"; 
     }); 
     self.editUrl = ko.computed(function() { 
      return '/Containers/Edit/' + data.Id; 
     }); 

     self.qrUrl = ko.computed(function() { 
      return '/Qr/Index/10?entity=' + data.Id; 
     }); 
    } 
function ContainersViewModel() { 
     var self = this; 
     self.containers = ko.observableArray([]); 
     self.counter = ko.computed(function() { 
      return self.containers().length; 
     }); 

     $.getJSON("/Containers/Json", function (data) { 
      var containers = $.map(data, function (item) { 
       return new Container(item); 
      }); 

      self.containers(containers); 
     }); 

    }; 
    ko.applyBindings(new ContainersViewModel()); 

Cảm ơn rất nhiều!

Nir

Trả lời

4

Các foreach ràng buộc tùy chọn afterRender có thể làm những gì bạn đang tìm kiếm, phần Bí quyết là để có thể biết rằng phần tử là phần tử cuối cùng. Điều đó có thể được giải quyết bằng cách sử dụng các đối số được cung cấp như được hiển thị trong http://jsfiddle.net/n54Xd/.

Chức năng:

this.myPostProcessingLogic = function(elements, data) { 
    if(this.foreach[this.foreach.length-1] === data) 
     console.log("list is rendered"); 
}; 

sẽ được kêu gọi mọi phần tử nhưng "nếu" sẽ chắc chắn rằng mã chỉ chạy cho các phần tử cuối cùng.

+0

cảm ơn Ricardo !, tôi đã thử nó, nhưng biểu thức này: 'this.foreach [this.foreach.length - 1]' trong phần 'if statement' luôn luôn đánh giá là không xác định. bất kỳ suy nghĩ nào? –

+0

xấu của tôi - tôi vô tình đã viết chức năng ngay bên ngoài viewmodel chính nó (một điều buổi sáng ..) cảm ơn! –

2

Cố gắng đăng ký theo cách thủ công trên các thay đổi mảng. Bằng cách sử dụng subscribe, bạn sẽ được thông báo về sửa đổi mảng.

Nếu bạn đăng ký sau khi áp dụng cuộc gọi bắt đầu, bạn sẽ được thông báo sau quá trình làm mới chế độ xem.

See fiddle

var ViewModel = function() { 
    var self = this; 

    self.list = ko.observableArray(); 

    self.add = function() { 
     self.list.push('Item'); 
    } 
    self.list.subscribe(function() { 
     alert('before'); 
    }); 
}; 
var vm = new ViewModel(); 
ko.applyBindings(vm); 

vm.list.subscribe(function() { 
    alert('after'); 
}); 

Tôi hy vọng nó giúp.

+0

Cảm ơn Damien !, nhưng đó không phải là những gì tôi nghĩ.ví dụ của bạn sẽ chỉ hoạt động sau khi thêm hoặc xóa các phần tử, nhưng đó không phải là thứ tôi sẽ làm với bộ sưu tập này. theo cách của nó bây giờ, nó xuất phát từ db để xem, và chỉ được hiển thị. chỉ có bấy nhiêu thôi. Tôi cần sự kiện được kích hoạt ngay sau khi mục cuối cùng được hiển thị trong vòng lặp –

+0

Xin chào Nir, tôi đã thêm bộ hẹn giờ để mô phỏng cuộc gọi webservice như bạn có thể thấy thông báo sau khi đã hiển thị các mục. http://jsfiddle.net/bUJmu/2/ – Damien

1

Sử dụng van tiết lưu mở rộng, cách này tính toán sẽ được gọi là một lần sau khi bạn đã hoàn thành Populating mảng:

self.counter = ko.computed(function() { 
     return self.containers().length; 
    }).extend({ throttle: 100 }); 
+0

Tôi thích câu trả lời này. Rất đơn giản và chỉ là những gì tôi cần để giải quyết vấn đề cân bằng cột bảng tương tự xảy ra sau mỗi hàng được hiển thị. Cảm ơn! –

2

Tôi đã thành công khi sử dụng câu trả lời của Ricardo Medeiros Penna chỉ với một chút tinh chỉnh.

this.myPostProcessingLogic = function(elements, data) { 
     if(this.foreach._latestValue[this.foreach._latestValue.length-1] === data) 
     console.log("list is rendered"); 
    }; 

Tôi phải thêm _latestValue để lấy giá trị độ dài và giờ nó đang hoạt động như mong muốn.

+0

_latestValue là biến riêng tư. Không chắc chắn nếu nó sẽ được an toàn để truy cập trực tiếp. Vì vậy, sử dụng 'this.foreach()' để thay thế. Không thực sự là một sự khác biệt lớn tho 'this.myPostProcessingLogic = function (phần tử, dữ liệu) { var underLyingArray = this.foreach(); nếu (underLyingArray [underLyingArray.length - 1] === dữ liệu) console.log ("danh sách được hiển thị"); }; ' – pravin

+0

Cảm ơn bạn đã cập nhật pravin – JaxCoder

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