2011-08-30 13 views
6

JQuery Mobileでknockoutjs(非常に新機能)を使用しています。私はフィルター結果をバインドするリストビューを持っています。私が初めて自分のデータをロードした後、私はJQMは私のリストのスタイルを変更するために変更のリストビューを自動的に更新 - knockoutjsとJQuery Mobile

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

を呼び出す必要があり、これは素晴らしい作品。

私のリストをフィルタリングすると、それが再レンダリングされ、スタイルが再び失われ、どこでリフレッシュを再度呼び出すべきかわかりません。

次のように私のHTMLは次のとおりです。

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

私のノックアウトJSは次のとおりです。

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'); 
} 

私は、私が行方不明だということは非常に愚かな何かがあることを確信しています...

感謝あなたの時間のために。

答えて

14

この問題は、KOフォーラムで数回発生しています。

1つの方法は、filteredItemsにバインドされたバインドを作成し、リストビューの更新を実行することです。

それは次のようになります。さて、あなたはコンテナ上でこれを置く(または実際に任意の要素の上に)、あなたはそれが同様に依存することを観察可能に渡す

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

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

ありがとう、私は前にこれを遭遇しましたが、このバインディングを私のforeachにどのように適用するのか分かりません。 – jimjim

+0

これは実際にはどの要素にでも置くことができます。 'data-bind ="テンプレート:{name: 'myTemplate'、foreach:filteredItems}、jqmRefreshList:filteredItems " –

+0

ありがとうRP!治療をしました。 BTW knockmeoutは素晴らしいサイトです。 – jimjim

3

作業コード全体をjsfiddleに投稿できますか?私は同じ問題を抱えているので、私はあなたのソリューションを試しましたが、それでも動作しません。

[編集]:[OK]を、それはこのように私のためにうまく働いた:

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

これは私のラップトップを窓から投げることから私を救った、ありがとう! –

+0

私の場合、ObservableArrayを返していました。 これを使用するには、私はする必要がありました: data-bind = "テンプレート:{名前: 'myTemplate'、foreach:filteredItems()}" – Adaptabi

1

前の2つの答えの構築、ここで少しより完全なものです。それはあなたが(コメント内すなわちforeachの)結合無容器を使用することができ、および例外を処理することによりjQMページのライフサイクルではなく、タイムアウト後に解雇されたリフレッシュの問題を裏:

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. 
     } 
    } 
    } 
}; 

complete worked example up on my blogがあります。希望が助けてくれる!

関連する問題