2017-01-28 13 views
0

ここでは私が作業しているコードです。コンソールログには、onFilterChangeメソッドが2回呼び出されていることが表示されています(「selectタグ」内の各関数定義に対して1回)。データバインドで「イベント:{change:onFilterChange}」を変更する必要があります過去に私のために働いているので、何の使用「()=> onFilterChange」私はKnockout.jsに慣れていないよん、と私たちはES6をサポートしていません。ページの読み込み時にKnockout.js関数が実行されないようにするにはどうすればよいですか?

function ProductionsView() { 
 
    var self = this; 
 

 
    self.showDateFilter = ko.observable(true); 
 
    self.showCategoryFilter = ko.observable(true); 
 
    self.showDateFilter = ko.observable(true); 
 

 
    self.onFilterChange = function(data,event) { 
 
     if (self.init()) { 
 
      self.doFilter(); 
 
      console.log("onFilterChange was called. This is happening twice on page load before interacting with the filter. "); 
 
     } 
 
    }; 
 

 

 
    self.doFilter = function() { 
 
     var df = self.selectedDateFilter(); 
 
     var cf = self.selectedCatFilter(); 
 

 
     if (typeof cf == 'undefined' || typeof df == 'undefined') { 
 
      return; 
 
     } 
 
     // these are all defined as observables too, but not important since it's the "onFilterChange" that I don't want to call 
 
     self.amFiltering("All" !== df || "All" !== cf); 
 
     self.allCatAndDate("All" === df && "All" === cf); 
 
     self.offset(0); 
 
     self.doAjaxSearchFiltered(true); 
 
    }; 
 
} 
 

 
var pv = new ProductionsView(); 
 
ko.applyBindings(pv);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div data-bind="visible: showDateFilterBar()"> 
 
    <select data-bind=" 
 
    value: selectedCatFilter, 
 
    event: { change: onFilterChange }, 
 
    visible: showCategoryFilter() 
 
    "> 
 
    <option value="all">all</option> 
 
    <option value="cat1">cat1</option> 
 
    </select> 
 
    <select data-bind=" 
 
    value: selectedDateFilter, 
 
    event: { change: onFilterChange }, 
 
    visible: showDateFilter() 
 
    "> 
 
    <option value="all">all</option> 
 
    <option value="date1">date1</option> 
 
    </select> 
 
</div>

+0

selectedCatFilterおよびselectedDateFilter、observableまたはcomputedとは何ですか?それらのコードを表示できますか? –

+0

ページの読み込み時に実行したくない場合は、いつ実行しますか?そのイベントが発生するまで 'applyBindings()'を呼び出すのを待って、そのイベントを使って呼び出しをトリガすることができますか? – coralvanda

+0

@JasonSpake申し訳ありませんが、私はその観察可能な宣言を.に追加しました。@coralvは、 'applyBindings()'を使用するためのこの良い文書です:http://stackoverflow.com/questions/18990244/whats-the-applybindings-second-parameter-used -for どのフィルタを選択するかを選択するときに、メソッドを 'onchange'と呼ぶのが好きです。 'applyBindings(self、document.getElementById(" date-results "))'を追加しますか? –

答えて

0

はい、間違ったノックアウトを使用しています。ノックアウトはすべて自動値の依存関係に関するもので、通常は「変更」イベントハンドラをまったく設定する必要はありません。

observablesを設定してサブスクライブします。たとえば、バインドされたUI要素がユーザーによって変更された場合、またはのうちの1つがの依存関係が変更された場合など、それらが変更されたときに通知されます。

観察可能な値を購読するには、computedまたは.subscribe()の中でそれらを直接使用してください。どちらも下に示されています。コードサンプルを実行して実際の動作を確認します。

function ProductionsView() { 
 
    var self = this; 
 

 
    // values 
 
    self.selectedDateFilter = ko.observable("all"); 
 
    self.selectedCatFilter = ko.observable("all"); 
 
    
 
    // computed values 
 
    self.amFiltering = ko.computed(function() { 
 
     return self.selectedDateFilter() !== "all" || 
 
       self.selectedCatFilter() !== "all"; 
 
    }); 
 
    self.allCatAndDate = ko.computed(function() { 
 
     return self.selectedDateFilter() === "all" && 
 
       self.selectedCatFilter() === "all"; 
 
    }); 
 

 
    // subscriptions 
 
    self.amFiltering.subscribe(function (value) { 
 
     console.log("searching with filter=" + value); 
 
     //self.doAjaxSearchFiltered(value); 
 
    }); 
 
} 
 

 
var pv = new ProductionsView(); 
 
ko.applyBindings(pv);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<select data-bind="value: selectedCatFilter"> 
 
    <option value="all">all</option> 
 
    <option value="cat1">cat1</option> 
 
</select> 
 

 
<select data-bind="value: selectedDateFilter"> 
 
    <option value="all">all</option> 
 
    <option value="date1">date1</option> 
 
</select> 
 

 
Viewmodel: 
 
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

あなたがオブジェクトとしてAjaxのパラメータが含まれて計算された値を作成する限り行くとこのように、それを購読することができます。

self.searchParams = ko.computed(function() { 
    return { 
     date: self.selectedDateFilter(), 
     cat: self.selectedCatFilter() 
    }; 
}); 

self.searchParams.subscribe(function (params) { 
    return $.get("/your/url", params).done(function (data) { 
     // populate your observables with new data 
    }); 
}); 

この方法でのAjax関連する変更が発生すると、リクエストが自動的にトリガーされます。

0

私は、あなたの初期値がselect要素に渡されるときに、変更イベントをトリガするのはapplyBindings自体であると推測しています。

マークアップのイベントバインディングではなく、オブザーバ自身の変更イベントをモデルに登録する必要があります。

self.selectedCatFilter.subscribe(onFilterChange); 

self.selectedDateFilter.subscribe(onFilterChange); 
関連する問題