gpt4 book ai didi

javascript - 当主干 View 被渲染时得到通知

转载 作者:行者123 更新时间:2023-11-30 07:05:36 25 4
gpt4 key购买 nike

我正在开发一个 Backbone.View,它应该将一个集合呈现为一个可滚动的列表。

作为初始渲染的一部分,我需要访问一些布局属性(例如 clientWidth),这些属性仅在 View 渲染后可用。

我的问题是,我怎么知道 View 已添加到 DOM 中?


使用 Backbone.View 通常有两种方法将 View 附加到 DOM:

  1. 创建 View > 渲染它 > 附加它:

    view = new MyList().render()
    $('#dummy').append(view.$el)
  2. 创建 View 并就地渲染它:

    new MyList({el: '#dummy'}).render()

注意:我知道 (1) 和 (2) 并不完全等价,这不是重点。


让我们考虑一下我的列表是这样定义的:

class MyList extends Backbone.View
render: ->
@$el->html( ... )
@

layout: ->
max = $el.scrollWidth - $el.clientWidth
# ... disable / enable scrolling arrows based on max ...

如何确保在 MyList 附加到 DOM 后调用 layout()?

最佳答案

我曾经遇到过这个问题,有些模式可以提供帮助。 Backbone 为您提供工具,但不告诉您如何使用它们。在使用它时建立良好的模式非常重要。我使用了两种不同的模式来帮助解决这个问题。

1) 根据您的应用程序的工作方式,确保始终调用 attached() 方法或触发 attached 事件可能很容易也可能很难在渲染它并将其附加到 DOM 后查看。就我而言,这很容易,因为我创建了一个架构,我可以在一个中心位置处理它。

2) 如果您总是在渲染后立即将您的元素附加到 DOM - 特别是在您渲染后的任何时候,通过在异步回调中这样做而不延迟附加,那么在您的 render() 函数中,您可以推迟对 layout() 或附加后需要运行的任何内容。像这样:

var MyList = Backbone.View.extend({
render: function() {
/* rendering logic goes here */

// Notice that the timeout is 0 - you can actually not even pass this argument
// but I wanted to emphasize that there is no delay given.
setTimeout(this.layout, 0);

return this;
},

layout: function() {
// This code won't be run until after this.el is attached to the DOM
}
});

var view = new MyList().render();
$('#dummy').append(view.$el);

Javascript 是而且永远是单线程的。 I/O 可以异步完成,但任何实际需要 JS 引擎时间的东西都不能与其他 JS 代码并行运行。当您在没有最后一个参数或值为 0 的情况下调用 setTimeout() 时,它实际上会将其排队以在当前正在执行的代码完成后尽快运行完成。

如果您遵循始终在调用 render() 后立即附加到 DOM 的模式,则可以利用这一事实 - 在当前执行的代码完成运行并将控制权返回给JS 引擎运行接下来排队的任何东西。当 setTimeout(func, 0) 排队的函数运行时,您就可以知道您的 View 已附加到 DOM。请注意,这与 _.defer() 相同。确实如此,但我想为您解释一下。

再次强调,建立模式非常重要。如果您从不保持一致并且没有在您的应用程序中建立模式,那么您将没有任何保证并且您将失去依赖此机制的能力 - 以及您可能能够建立的其他机制。希望这对您有所帮助!

关于javascript - 当主干 View 被渲染时得到通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12285900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com