【发布时间】:2017-05-26 23:10:58
【问题描述】:
我希望在模板内容发生变化时捕捉事件;也就是说,模板每次重新渲染之后。
例子:
<script type="text/html" id="myTemplate">
<span data-bind="text: myBoolean"></span>
</script>
<!-- ko template: { name: 'myTemplate', afterRender: myafterRenderCallback } -->
<!-- /ko-->
在 javascript 中,我只有:
self.myBoolean = ko.observable(true);
这个 observable 发生了变化,比如说,有一些其他按钮,点击它会改变 myBoolean 的值。
因此,每次 myBoolean 更改时,模板的内容都会更新。当模板的重新渲染完成时,我需要回调函数,这意味着它已经将值从 true 更改为 false,或者从 false 更改为 true。
我尝试了两种解决方案,但都没有奏效:
afterRender: myafterRenderCallback仅在第一次渲染模板时调用一次。每次 myBoolean 更改后都不会调用它。-
对 myBoolean 使用类似监听器:
self.myBoolean.subscribe(function() {
//待办事项
});
第二种方法的问题是,订阅函数被调用太快,甚至在模板更新视图中的 myBoolean 之前,这导致了这个问题,这是一个很长的故事(我可以,如果你真的想知道:比如一个简单的例子,我需要访问DOM,模板比上面那个更复杂)。
我尝试了另一种方法,使用 setTimeout,所以在 myBoolean 更改后等待 2 秒左右,但这更像是一个肮脏的解决方案。
欢迎提出任何建议。
==================================
按要求提供有关模板内容的信息:
所以我在这里为您提供更多信息:我有一个淘汰组件,称为 ToolBar。它是一个模板;它只是一个带有一些 CSS 的容器。仅此而已。它包含一组按钮。一些按钮有时是可见的,有时是不可见的(我们称之为按钮的状态)。现在,每当按钮更改其状态时,我们希望残障用户能够仅使用键盘(它是 WAI-ARIA)浏览按钮,通常按 Tab 键或箭头键。
问题是,每当按钮动态更改其状态时,它都会破坏键盘的可访问性。这种损坏功能的原因是通过键盘控制导航的(无论哪种)技术都不知道按钮的新更改状态。示例:按 Tab 或箭头键只会跳过新可见的按钮,或者卡在新不可见的按钮上。或者解决这个问题,我需要在 DOM 完成重新渲染后简单地刷新工具栏(有刷新功能),以便 WAI-ARIA 知道所有按钮的最终状态,从而启用导航键盘。
因此,刷新函数需要在模板的整个重新渲染完成时调用,即当所有按钮都完成更改状态时。因此,我需要那个事件,或者那个事件的回调。
依赖 observables(上面提到的方法 2)会导致一个问题:observable 的 subscribe 函数在 DOM 更新之前被调用,因此刷新函数被称为 DOM 也被更新,因此为时过早,并且键盘只是对按钮的旧状态进行操作,这导致导航被破坏。
请注意这里没有异步进程。按钮的状态会随着选择表格的哪一行而改变,或者在一个简化的例子中,让我们假设在其他地方还有一些其他按钮,点击它们会改变工具栏中按钮的状态。
【问题讨论】:
-
没有内置的方法来监视整个模板的更改。渲染后,您必须注意单个可观察对象的更改,这是您在第二个示例中尝试做的事情。我认为我们确实需要更多关于在这种情况下出了什么问题的信息。听起来您的模板中某处有一个异步进程需要在继续之前完成,因此您可能需要识别该进程并更改它以返回延迟对象。
-
我刚刚阅读了您的问题。我发现很难从您概述的人为场景中解读您的实际用例。我从一开始就使用淘汰赛,而且经常当我发现自己处于这种情况时,我通常会遇到架构问题,而不是淘汰赛问题。如果您进一步解释实际实现,也许可以提供更合理的建议。当然只是我的两美分。
-
@PimBrouwers 你是对的。有时它只是一个架构问题。刚刚更新了我的帖子,添加了很长的解释。希望它能更好地澄清事情。
-
看来我需要监听 DOM 变化。刚抬头发现MutationObserver。所以这可能与淘汰赛无关。还有比这更好的解决方案吗?
-
对我来说,这句话突出包含答案:“问题是,每当一个按钮动态改变其状态时,它会破坏键盘的可访问性。”——对我来说,这表明你需要自定义绑定,在“更新”函数中指定您的可访问性键盘绑定。这会将可观察的状态更改(或计算,如果您正在收听多个)重新绑定到仅活动按钮。此自定义绑定可以放置在组件内的最高级别 DOM 元素上,以使其能够访问它可能需要操作的所有 HTML。
标签: javascript html templates knockout.js callback