- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有deferred updates启用。
我有两个组件。
第一个是列表,它被简单地实现为带有 foreach 数据绑定(bind)的 div:
<div class="list-people" data-bind="foreach: { data: people, afterRender: afterRenderPeople }">
<!-- ko component: { name: "listitem-person", params: { person: $data } } --><!-- /ko -->
</div>
第二个是列表项:
<div class="listitem-person">
<span data-bind="text: Name"></span>
</div>
afterRender
为 foreach
中的每个项目调用.
我的 afterRenderPerson
功能很简单:
public afterRenderPerson = (elements: any[], data: Person) => {
let top = $(element[0]).offset().top;
scrollTo(top);
};
问题是当afterRenderPerson
称为子组件 listitem-person
尚未呈现。
表示传递给afterRenderPerson
的元素数组有 4 个节点:
\n
的文本节点即换行。<!-- ko component: { name: "listitem-person", params: { person: $data } } -->
的注释节点.<!-- /ko -->
的注释节点.\n
的文本节点即换行。这些都不适合获得 top
像素,即使它们是,正在呈现的子组件也可能会影响该位置的布局,从而改变我尝试获取的像素值。
最佳答案
不幸的是,documentation for foreach 似乎没有考虑组件的延迟性质。
If you need to run some further custom logic on the generated DOM elements, you can use any of the afterRender/afterAdd/beforeRemove/beforeMove/afterMove callbacks described below.
Note: These callbacks are only intended for triggering animations related to changes in a list.
我遇到过两种变通办法,都不是很好,但这就是为什么它们是变通办法而不是解决方案!
user3297291 在评论中提出了创建放置在子组件上的 scrollTo
绑定(bind)的建议。
Only workaround I can think of is to define a custom scrollTo binding and include it in the component template... Quite easy to implement, but still feels hacky and makes your inner component harder to reuse. You might also want to track this feature request – user3297291
这只是一个 custom binding它根据提供给它的值有条件地执行一些代码。
在将 HTML 插入 DOM 之前,不会调用绑定(bind)。这并不完美,因为稍后对 DOM 的更改可能会影响插入的 HTML 元素的位置,但它应该适用于许多情况。
虽然我不是很热衷于必须修改子组件,但我更喜欢将其封装在父组件中的解决方案。
第二种解决方法是通过其 ID 检查子组件 HTML 元素是否存在于 DOM 中。因为我不知道它们什么时候会出现,所以这必须在某种循环中完成。
while 循环不适合,因为它会在“紧密”循环中过于频繁地运行检查,因此使用 setTimeout
。
setTimeout
是一个可怕的 hack,使用它让我觉得很脏,但它确实适用于这种情况。
private _scrollToOffset = -100;
private _detectScrollToDelayInMS = 200;
private _detectScrollToCountMax = 40;
private _detectScrollToCount = 0;
private _detectScrollTo = (scrollToContainerSelector: string, scrollToChildSelector: string) => {
//AJ: If we've tried too many times then give up.
if (this._detectScrollToCount >= this._detectScrollToCountMax)
return;
setTimeout(() => {
let foundElements = $(scrollToChildSelector);
if (foundElements.length > 0) {
//AJ: Scroll to it
$(scrollToContainerSelector).animate({ scrollTop: foundElements.offset().top + this._scrollToOffset });
//AJ: Give it a highlight
foundElements.addClass("highlight");
} else {
//AJ: Try again
this._detectScrollTo(scrollToContainerSelector, scrollToChildSelector);
}
}, this._detectScrollToDelayInMS);
this._detectScrollToCount++;
};
我确保对其运行时间设置了限制,因此如果出现问题,它不会永远循环。
可能应该注意到这个问题有一个“终极”解决方案,那就是 TKO,又名 Knockout 4。
但这还不是“生产就绪”。
How to know when a component has finished updating DOM?
brianmhunt commented on Jun 20
knockout/tko (ko 4 candidate) latest master branch has this.
More specifically, the applyBindings family of functions now return a Promise that resolves when sub-children (including asynchronous ones) are bound.
The API isn't set or documented yet, but the bones have been set up.
关于javascript - 使用 KnockoutJS,在 foreach 中呈现后如何滚动到组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45595356/
这是一个假设性问题。如果我有来自 3 个单独的 sql db 查询的 3 个数组,这些查询都与另一个数组相关。例如…… //db schools id | school_name classes id
在我的应用程序中,我使用 scrape(string url) 方法从网页中抓取链接。可以说它每次都返回我 10 个 url。 我想从每个抓取的 url 中抓取 10 个链接。 长话短说: (第 1
我的java7代码: final Map result = new HashMap<>(); final Set> classes = getClasses(co.glue()); for (fina
是否可以在 SwiftUI 中设置变量,例如在这样的 ForEach 中: struct ContentView: View { var test: Int var body: som
在 D、int、uint 中使用 foreach 时,循环索引的首选类型是什么?或者只是通过省略类型自动实现? 最佳答案 一般来说,索引应该是size_t。与长度相同。如果您尝试使用 int 或 ui
根据 http://dlang.org/statement.html 的“Foreach 限制”部分以下代码 int[] a; int[] b; foreach (int i; a) { a
在什么情况下我们应该在 JDK 8 中使用旧的 foreach 循环遍历新的 collection.forEach() 还是最好的做法是转换 every foreach 循环?是否存在任何重要的性能差
获得类似东西的惯用方法是什么? ((fn [coll] (function-body)) [:a :b :c :d]) -> [[:a :b][:a :c][:a :d][:b :c][:b :d][
我正在创建一个基于 who is it? 的 Java 应用程序。现在我正在制作一种方法,在回答问题时我需要其他卡片。 我有两个列表: 列表是一个 ImageView 列表,其中我有卡片必须代表的 2
我希望有人能在我发疯之前帮助我。 我有 3 张 table : Table A SELECT companypk, companyname, logo, msscope FROM global_com
我正在尝试将多个字符串添加到 C# 中的 MailAddress。 如果我使用ForEach,我的代码会是这样 foreach (var item in GetPeopleList()
我没有太多的 C# 经验,所以如果有人能指出正确的方向,我将不胜感激。我有一个引用对象变量的 foreach 循环。我希望在主循环中创建另一个 foreach 循环,将当前变量与对象数组中的其余变量进
下面的代码每 60 秒删除文件夹“Images”中的文件,它可以工作,但是当文件夹为空时它会显示:警告:为 foreach() 提供的参数无效如果没有文件,如何解决这个问题,说“文件夹为空而不是那个警
我需要在两种不同的模式下运行,因此“if”(第二个稍后构建一个大的 csv) 下面对于单个实例运行正常,但在第二个 (*) 的加载时间上失败,因为在前 7k 行中的每一行上运行。 我想避免可怕的事情
我们可以使用以下两种方法实现类数组对象的迭代: let arrayLike = document.getElementsByClassName('dummy'); [].forEach.call(ar
我有这个代码 ... 它说: Attribute value invalid for tag forEach according to TLD 最佳答案 forEach标签不支持 valu
我在 SwiftUI 中有一个像这样的 ForEach: ForEach(entries) { (e: MyType) in NavigationLinkItem(entry: e) } 现在我
我无法在一个 Foreach 或 Foreach-Object 循环中使用多个命令 我的情况是—— 我有很多文本文件,大约 100 个。 所以他们被阅读 Get-ChildItem $FilePath
我必须从 json 文件(实际上是 2 个 json 文件)执行 ForEach,因此我执行 2 forEach,代码是 table { font-family: arial, sans-
我对编程很陌生,当我执行 forEach 函数时,我的应用程序返回错误。我的controller.js中有以下代码 $scope.ajaxRequest = A.Game.get({action: '
我是一名优秀的程序员,十分优秀!