Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ember.js 对嵌套视图使用'afterRender'钩子_Ember.js - Fatal编程技术网

Ember.js 对嵌套视图使用'afterRender'钩子

Ember.js 对嵌套视图使用'afterRender'钩子,ember.js,Ember.js,我想做的很简单:在当前路径中的所有视图完成渲染后,从jQuery和jsPlumb库执行一些(实际上是很多)视图层Javascript代码。在得到一些帮助并发现ember latest刚刚更新为包含afterRenderhook之后,我决定升级。我现在拥有全能的afterRenderhook 我插入到dom中的所有视图都有一个与其关联的块类。因此,我测试是否所有视图都在dom中的方法是使用$('.block').size()并查看它是否与预期的数字匹配 然而,当我尝试在我的应用程序中使用这个钩子时

我想做的很简单:在当前路径中的所有视图完成渲染后,从jQuery和jsPlumb库执行一些(实际上是很多)视图层Javascript代码。在得到一些帮助并发现ember latest刚刚更新为包含
afterRender
hook之后,我决定升级。我现在拥有全能的
afterRender
hook

我插入到dom中的所有视图都有一个与其关联的
类。因此,我测试是否所有视图都在dom中的方法是使用
$('.block').size()
并查看它是否与预期的数字匹配

然而,当我尝试在我的应用程序中使用这个钩子时,我面临一些问题。在调用
connectOutlets
之后,我首先尝试在路由器中调用
afterRender
。当我打印dom中的块数时,我总是只得到1个块,而应该有10个

如果我将此代码放入本地
视图的
didInsertElement

didInsertElement: () ->
    knob = this.$("##{@get 'knobId'}")
    name = this.$(".name")
    main = this.$(".main") #block html content will be injected into main
    knob.hide()

    Ember.run.scheduleOnce('afterRender', this, ()->
      console.log ">> block count: ", $(".block").size()
    )
    ...
然后我得到以下输出:

>> block count: 1
>> block count: 10
>> block count: 10
>> block count: 10
>> block count: 10
>> block count: 10
>> block count: 10
>> block count: 10
>> block count: 10
>> block count: 10
出于某种原因,在第一次迭代中,我只得到dom中的1个块,然后得到所有10个块。我不知道为什么。但这里的主要问题是,如果我将钩子放在
didInsertElement
中,代码将根据数据执行任意数量的视图(在本例中为10)。但是,我只想在所有视图完成渲染后运行此代码一次

请注意,我正在使用的视图具有嵌套数据。我试过了,但我失败了,因为我觉得这一切似乎都很有效。可能是因为我的视图太大太复杂,导致了一些同步问题?无论如何,我认为我们可以用小提琴来讨论解决方案,我可以在本地测试它

我试图绕过这个问题的一个技巧是使用
Ember.run.later
将我的代码安排在500毫秒延迟后运行。这确实解决了我本地机器上的问题。但是,使用计时器来执行此操作非常麻烦,而且工作不可靠,因为不同的浏览器或计算机可能需要更长的时间来渲染视图

这是一个虽然复制,我已经花了很多时间试图找到一个解决方案。如果能在这里重现问题或找到解决方案,我将不胜感激

编辑(解决方法):感谢look帮助我解决此问题,通过查看,我想出了以下临时解决方法,我将其放入路由器代码中:

    # Keep trying until there are two or more blocks in DOM
    blocksLoaded = ->
      console.log "blocks number ...: ", $('.block').size()
      if $('.block').size() > 1
        console.log "Yay!...we have ", $('.block').size()
        startTraversingBlocks()
      else
        Ember.run.next(this, ()->
          blocksLoaded()
        )

    blocksLoaded()
这将产生:

blockies number ...: 0
blockies number ...: 1
blockies number ...: 1
blockies number ...: 1
...
blockies number ...: 1
blockies number ...: 10
Yay!...we have 10
正如Luke指出的,这里的问题是,我的嵌套视图是通过几个运行循环进行渲染的。当我刷新浏览器时,我每次都会得到不同数量的
块数…:1
输出,在测试期间的4到10次之间


在我看来,这不是一个很好的解决方案,但它似乎适用于我的用例。我觉得这里需要另一个钩子,当保证视图中的所有元素都可以通过jQuery选择器访问时,它允许用户访问DOM,但也许我在这里遗漏了一些东西。

我问了Kris Selden这个问题,他说“afterRender是在该运行循环的渲染队列完全刷新之后;我猜这不止是一个循环”


最有可能的情况是您有一个记录数组加载。可能是从一个项目开始,然后再加载9个项目。如果排除数据加载,可能您有一个
Ember.run.next
Ember.run.later
在代码中的某个地方?

我注释掉了
Ember.run
的所有其他用法,但我仍然得到了答案只有一个视图。这听起来更像您描述的第一个场景。我在这个视图中使用的数据是嵌套的,正如我所提到的,并且其中有视图数组。我认为我没有明确告诉ember单独呈现第一个视图。如果我们假设这是第一个场景,您能解释一下我可以做些什么来缓解这个问题吗e问题?如果您知道您期望的项目多于一项,则可以将视图包装为{{{If…}handle bars helper使用的条件属性在数量超过1时计算为true。我们在应用程序中遇到了类似的问题,因为1个项被侧加载,然后我们执行了一个查询来加载其余项。好的,这听起来很有希望,但我不确定我是否理解得很好。我应该将此类条件放在哪里?在视图类定义中?这是吗您可以在我提供的小提琴中向我展示什么?在我的车把中,我通过引用
this
嵌套视图,因此我不清楚如何实现您所说的内容。是的,我希望有两个或多个项目(或视图)。这里有一个更新,用于显示“如果”的位置。