【问题标题】:How to prevent content from scrolling when Meteor updates the collectionMeteor 更新集合时如何防止内容滚动
【发布时间】:2013-08-29 23:55:13
【问题描述】:

我的问题与this onethat one 非常相似,但并不完全相同。

我的 Meteor 应用程序中有以下模板:

<template name="items">
    <div class="mainframe">
    <h3>Available items:</h3>
        <div class="items-table-container">
            <table class="table table-hover">
                <tbody>
                    {{#each all_items}}
                       {{> item}}
                    {{/each}}
                </tbody>
            </table>
        </div>
    </div>
    <div class="btn-group">
    <button id="create" class="btn">Create new item</button>
    </div>
</template>

模板函数很简单:

Template.items.all_items = function () {
    return Items.find({}, {sort: {name: 1}}).fetch();
}

还有一个绑定到#create 按钮的事件,它将一个新项目插入到 Items 集合中,并且工作正常。

现在最重要的部分是 CSS:

.items-table-container {
    height:340px;
    overflow-y: scroll;
}

所以基本上我希望我的表格在固定大小的区域内有可滚动的内容。 当我在一个浏览器中向下滚动项目表的内容然后在另一个浏览器中添加一个新项目时,问题就开始了。第一个浏览器更新项目列表并将内容滚动回顶部位置。

问题是如何防止单个模板的自动更新?我认为在这种特殊情况下,我实际上需要像传统网页更新这样的东西:如果用户没有立即看到新添加的项目,而是在他重新加载页面之后看到,那也没关系。

另一个想法是做某种分页而不是可滚动的内容。我认为这会解决问题,但这会更复杂,我想避免这种情况。

我认为理想情况下我希望能够告诉 Meteor,我希望 Meteor 不是在模型更改时而是通过请求更新模板。

【问题讨论】:

    标签: meteor


    【解决方案1】:

    将您的项目列表放在可滚动 div 容器内的另一个模板中:

    <template name="items">
        <div class="mainframe">
        <h3>Available items:</h3>
            <div class="items-table-container">
                <table class="table table-hover">
                    <tbody>
                        {{> myitems}}
                    </tbody>
                </table>
            </div>
        </div>
        <div class="btn-group">
            <button id="create" class="btn">Create new item</button>
        </div>
    </template>
    
    <template name="myitems">
        {{#each all_items}}
            {{> item}}
        {{/each}}
    </template>
    

    Javascript:

    Template.myitems.all_items = function () {
        return Items.find({}, {sort: {name: 1}}).fetch();
    }
    
    //Template.items.all_items = function () {
    // remove this helper
    //}
    

    这样您就可以保持反应性,而无需提出更新请求。只有可滚动框内的部分被重新渲染,保持可滚动容器滚动到的位置。

    编辑:要保留/冻结您的内容,您可以使用 preserve 函数,它需要一个 css 选择器作为输入。例如

    Template.items.preserve(['.items-table-container']);
    

    【讨论】:

    • 这样就解决了,谢谢!但是我相信应该有可能“冻结”渲染的模板,因为有时反应行为是不需要的。
    • 我不知道保留,但在使用保留重新渲染期间未保留滚动位置。但这将有助于在其他情况下冻结
    • #isolate、#constant 和 preserve 已全部删除:github.com/meteor/meteor/wiki/…
    【解决方案2】:

    隔离数组迭代。

    {{#isolate}}
      {{#each all_items}}
        {{> item}}
      {{/each}}
    {{/isolate}}
    

    【讨论】:

    • +1 这实现了将内容放在另一个模板中的相同效果,但如果您的代码以这种方式更有意义,则将其保留在相同的模板上下文中。
    • #isolate、#constant 和 preserve 已全部删除:github.com/meteor/meteor/wiki/…
    【解决方案3】:

    要使整个区域保持不变以使其不会重新渲染,您可以使用块助手 {{#constant}}。

    如果你有特定的 DOM 元素要保留,你可以使用 Template.myTemplate.preserve() 它将节点的选择器作为参数来保留。

    【讨论】:

    【解决方案4】:

    您还可以使用 jquery 句柄来固定滚动位置。我的用例是在主体文档中的当前滚动点上方插入一些内容,滚动文本更低。

    还不确定如何让流星在每次更新发布集时运行回调,但你应该明白了:

    before = document.body.scrollHeight
    // insert your elements
    after = document.body.scrollHeight
    
    if $(document).scrollTop() != 0
      # scroll us equal to the amount of scroll height added
      window.scrollTo(0, $(document).scrollTop()+(after-before) )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多