我使用knockout渲染一个可单击元素列表,这些元素可用作单选按钮。但是,由于这是一个水平列出元素的列表,当放入太多元素时,它可以在页面右侧运行(因为它们有时可能)。现在,我只是打破它并制作多行,但这对我想要的设计来说并不理想。
问题是我插入的组件具有可变宽度,具体取决于每个组件中列出的人员的名称。我想要做的是能够告诉我可以为给定的浏览器宽度放置多少组件,然后将其余组件隐藏在一个不同的可观察数组中,我可以以不同的方式呈现(使用下拉列表)。我不相信有任何简单的方法可以让我使用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
});
我想我的问题是,这是否真实可行?我想避免渲染它,然后获取每个元素的宽度,然后再次重新渲染或像那样凌乱/闪烁。我知道为了在调整窗口大小时动态更新它,我必须为元素添加触发器,但我甚至无法弄清楚我是如何做到这一步的第一步
编辑:所以,我捅了一下,最后决定我必须使用dom。我的解决方案看起来像这样: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 :(得分:1)
您将无法通过使用模型来执行此操作,因为您的问题依赖于DOM,并且viewmodel不知道它与DOM的关系。您可以在多个位置呈现相同的数据。
如果要控制数据的呈现方式,则需要custom binding handler。这是切实可行的,但这是一个复杂的问题。
答案 1 :(得分:0)
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同步更新。不是很好,但它是我现在最好的。