2011-08-30 27 views
6

Tôi đang sử dụng knockoutjs (rất mới với nó) với JQuery Mobile. Tôi có một listview mà tôi ràng buộc kết quả lọc. Sau khi tôi tải dữ liệu của mình lần đầu tiên, tôi phải gọiTự động làm mới xem danh sách trên thay đổi - knockoutjs & JQuery Mobile

$('ul').listview('refresh'); 

để JQM khôi phục lại danh sách của tôi, công trình này tuyệt vời.

Tuy nhiên khi tôi lọc danh sách của mình, nó được hiển thị lại và mất phong cách một lần nữa và tôi không thể tìm ra nơi để gọi lại làm mới.

html của tôi là như sau:

<p>Filter: <input data-bind="value: filter, valueUpdate: 'afterkeydown'" /></p> 
    <ul data-role="listview" data-theme="g" data-bind="template: {name: 'myTemplate', foreach: filteredItems }" /> 

My Knockout JS là:

var car = function (name, make, year) { 
    this.name = name; 
    this.make = make; 
    this.year = year; 
} 

var carsViewModel = { 
    cars: ko.observableArray([]), 
    filter: ko.observable() 
}; 

//filter the items using the filter text 
carsViewModel.filteredItems = ko.dependentObservable(function() { 
    var filter = this.filter(); 
    if (!filter) { 
     return this.cars(); 
    } else { 
     return ko.utils.arrayFilter(this.cars(), function (item) { 
      return item.make == filter; 
     }); 
    } 
}, carsViewModel); 

function init() { 
    carsViewModel.cars.push(new car("car1", "bmw", 2000)); 
    carsViewModel.cars.push(new car("car2", "bmw", 2000)); 
    carsViewModel.cars.push(new car("car3", "toyota", 2000)); 
    carsViewModel.cars.push(new car("car4", "toyota", 2000)); 
    carsViewModel.cars.push(new car("car5", "toyota", 2000));   
    ko.applyBindings(carsViewModel); 
    //refresh the list to reapply the styles 
    $('ul').listview('refresh'); 
} 

Tôi chắc chắn rằng có cái gì đó rất ngớ ngẩn mà tôi đang thiếu ...

Thank bạn cho thời gian của bạn.

Trả lời

14

Sự cố này đã xuất hiện trên diễn đàn KO một vài lần.

Một tùy chọn là tạo liên kết ràng buộc với filteredItems và chạy làm mới chế độ xem danh sách.

Nó có thể trông giống như:

ko.bindingHandlers.jqmRefreshList = { 
    update: function(element, valueAccessor) { 
     ko.utils.unwrapObservable(valueAccessor()); //just to create a dependency 
     $(element).listview("refresh"); 
    } 
    }; 

Bây giờ, bạn sẽ đặt này trên thùng sơn (hoặc thực sự trên bất kỳ phần tử) và vượt qua trong các quan sát mà bạn muốn nó phụ thuộc vào như:

<ul data-bind="jqmRefreshList: filteredItems"></ul> 
+0

Cảm ơn, tôi đã xem xét điều này trước đây, nhưng tôi không chắc chắn làm thế nào để áp dụng ràng buộc này vào foreach của tôi? – jimjim

+0

Thực sự bạn có thể đặt điều này trên bất kỳ yếu tố nào, kể cả cơ thể. Nếu bạn muốn giữ nó với mẫu của bạn, thì bạn có thể làm: 'data-bind =" template: {name: 'myTemplate', foreach: filtersItems}, jqmRefreshList: filtersItems "' –

+0

Cảm ơn RP rất nhiều! Làm việc một điều trị. BTW knockmeout là một trang web tuyệt vời. – jimjim

3

Bạn có thể đăng toàn bộ mã làm việc lên jsfiddle không? Bởi vì tôi có cùng một vấn đề và tôi đã thử giải pháp của bạn nhưng nó vẫn không hoạt động.

[Chỉnh sửa]: Ok, nó làm việc tốt đối với tôi như thế này:

ko.bindingHandlers.jqmRefreshList = { 
    update: function (element, valueAccessor) { 

     ko.utils.unwrapObservable(valueAccessor()); //just to create a dependency 
     setTimeout(function() { //To make sure the refresh fires after the DOM is updated 
      $(element).listview(); 
      $(element).listview('refresh'); 
     }, 0); 
    } 
}; 
+0

Điều này đã cứu tôi khỏi việc ném máy tính xách tay của tôi ra ngoài cửa sổ, cảm ơn! –

+0

Trong trường hợp của tôi, tôi đã trả lại một ObservableArray. do đó, để sử dụng nó, tôi cần phải làm: data-bind = "template: {name: 'myTemplate', foreach: filterItems()}" – Adaptabi

1

xây dựng trên hai câu trả lời trước, đây là một chút gì đó hoàn chỉnh hơn. Nó cho phép bạn sử dụng containerless ràng buộc (ví dụ: foreach trong bình luận), và đế vấn đề làm mới bị sa thải sau khi vòng đời trang jQM bằng cách xử lý trường hợp ngoại lệ chứ không phải là một thời gian chờ:

ko.virtualElements.allowedBindings.updateListviewOnChange = true; 
ko.bindingHandlers.updateListviewOnChange = { 
    update: function (element, valueAccessor) { 
    ko.utils.unwrapObservable(valueAccessor()); //grab dependency 

    var listview = $(element).parents() 
          .andSelf() 
          .filter("[data-role='listview']"); 

    if (listview) { 
     try { 
     $(listview).listview('refresh'); 
     } catch (e) { 
     // if the listview is not initialised, the above call with throw an exception 
     // there doe snot appear to be any way to easily test for this state, so 
     // we just swallow the exception here. 
     } 
    } 
    } 
}; 

Có một complete worked example up on my blog. Hy vọng rằng sẽ giúp!

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