2016-09-09 2 views
1

私はノックアウトを使用して、ラジオボタンとして機能するクリック可能な要素のリストをレンダリングしています。しかし、これは要素が水平にリストされているリストであるため、(時々あるように)あまりにも多くの要素が配置されていると、ページを右に走らせることができます。今、私はそれを壊して複数の行を作っていますが、これは私が持っていたいデザインには理想的ではありません。ノックアウトレンダリングされたコンポーネントの幅を計算する

問題は、挿入するコンポーネントが、各コンポーネントにリストされている人物の名前によって可変幅を持つことです。私がしたいのは、与えられたブラウザの幅に対していくつのコンポーネントを置くことができるのかを知ることができ、残りの部分を私が別の方法で(ドロップダウンを使用して)レンダリングできる異なる観測可能な配列に隠すことです。私は、これを行うためにCSSを使用する簡単な方法はないと信じています。なぜなら、これは全く別の要素でレンダリングする必要があるからです。私のViewModelで

コードは、このようなものになります。私は私の質問があると思い

self.personList = ko.observableArray(params.personList); 

self.visiblePersons = ko.pureComputed(function() { 
    var viewPortWidth = $("#personListContainer").width(); 
    var personArray = []; 
    $.each(personList(), function(person) { 
     var widthOfPersonElement = getPersonWidth(person); //not sure how to get the person width after render? 
     viewPortWidth -= widthOfPersonElement; 
     if (viewPortWidth >= 0) { 
      personArray.push(person); 
     } 
    }); 
    return personArray; 
}); 

self.overflowPersons = ko.pureComputed(function() { 
    //get all persons in the person list that AREN'T in the visible list 
    //this is the easy part 
}); 

を、これは可能でも現実的でしょうか?私はそれをレンダリングすることを避けたいですし、各要素の幅を取得してから、再度レンダリングしてください。ウィンドウがリサイズされたときに動的に更新するには、その要素のトリガーを追加する必要があることがわかりますが、この最初のステップをどのように実行するのか把握できません。

編集:私はちょっと突っ込んで、ドームを使わなければならないと決めました。

var getRenderedPersonWidth = function(person) { 
    var displayString = person.FullName + person.ID; 
    var element = document.createElement('span'); 
    $(element).text(displayString); 
    $(element).addClass(""); //class names of the element I'm rendering 
    $('#elementtorenderunder').append(element); 
    var width = $(element).width(); 
    $(element).remove(); 
    return width; 
} 

はあなたがレンダリングしているHTMLと同期して更新されたクラスを維持する必要があると思いますけれどもそれは実際にはかなり、非常によくない動作しますが、それは最高の:私は解決策は次のようになります私は今のところ持っている。

答えて

0

EDIT:私はちょっと突っ込んで、ドームを使わなければならないと決めました。

var getRenderedPersonWidth = function(person) { 
    var displayString = person.FullName + person.ID; 
    var element = document.createElement('span'); 
    $(element).text(displayString); 
    $(element).addClass(""); //class names of the element I'm rendering 
    $('#elementtorenderunder').append(element); 
    var width = $(element).width(); 
    $(element).remove(); 
    return width; 
} 

はあなたがレンダリングしているHTMLと同期して更新されたクラスを維持する必要があると思いますけれどもそれは実際にはかなり、非常によくない動作しますが、それは最高の:私は解決策は次のようになります私は今のところ持っている。

1

問題はDOMに依存し、viewmodelはDOMとの関係がわからないため、モデルで作業することでこれを行うことはできません。同じデータを複数の場所でレンダリングすることもできます。

データのレンダリング方法を制御する場合は、custom binding handlerが必要です。現実的に可能ですが、それは複雑な問題です。

+0

ありがとう、私は実際にそれを把握するために一時的にDOMを使用して終了しました。私はそれがドン・アグノスティックであるというあなたの意見を見ます。 – Mike

関連する問題