流星:强制渲染元素

时间:2017-12-06 11:40:39

标签: javascript meteor meteor-blaze

我的应用中有几次使用的通用模板:

<template name="genericCollapse">
  {{data-1}}
  <a href=# class='collapsed' data-toggle='collapse'
     data-target='#uniqueId'>Show/hide data-2</a>
  <div class='collapse' id='uniqueId'>
    {{data-2}}
  </div>
</template>

通过点击应用中的其他位置,data-1和data-2会同时更改(使用会话变量)。但是,如果模板已经在屏幕上,只有data-1和data-2正在改变,但div的崩溃状态(显然)保持不变。如果它之前是开放的,它仍然是开放的。

我想实现,每当data-1 / data-2发生变化时,div和a都会被迫再次处于崩溃状态。 我试着添加

<a href=# class='{{collapsed}}'

Template.genericCollapse.helpers({
  collapsed () {return "collapsed " + Random.Id()},
})

这不仅非常难看,而且也无济于事,因为div的类仍然存在&#34;崩溃显示&#34;即使有一个div的第二个助手,我也无法摆脱&#34; show&#34;。

重新渲染整个模板也是可以接受的,但我很难确定调用Blaze.render()的parentNode - 它永远不会相同 - 而且我也不确定在哪里放置这样的打电话正确。

这是怎么做到的?

4 个答案:

答案 0 :(得分:1)

看起来你正在与自举战斗。单击链接时,引导程序会添加show类,对吗?由于您的html标记未设置此类,因此您需要在基础数据更改时自行删除它。您可以通过观察数据的更改然后直接修改DOM来完成。

这是一个基本的例子:

Template.myTemplate.onCreated(function () {
  const query = MyCollection.find({},{fields: {data-1: 1, data-2: 1}});
  const handle = query.observeChanges({
    changed(id, fields) {
      $('.show').removeClass('show');
    }
});

这假定您要控制的字段为data-1data-2的集合。如果您的data-1data-2是执行某些计算的助手,那么您可能希望使用基于反应变量的Tracker来处理此问题。

答案 1 :(得分:1)

@Michel Floyd对抗自举是正确的。

但是,既然你说你正在使用Session vars,那么只需使用自动运行:

Template.genericCollapse.onRendered(function() {
  this.autorun(() => {
    const data1 = Session.get('data-1');
    const data2 = Session.get('data-2');
    if (data1 === someCondition || data2 === someOtherCondition) {
      this.$('.collapse').collapse('show');
    } else {
      this.$('.collapse').collapse('hide');
    }
});

如果data-1data-2发生变化,此功能将重新运行

答案 2 :(得分:1)

非常感谢你的帮助!

@Michel Floyd让我意识到我的问题不是由与Meteor相关的任何事情造成的,而是由引导程序引起的。

@Fred Stark为解决方案添加了一个很好的变化,他使用了更多流星风格的自动运行,他使用.collapse(&#39; hide&#39;)代替.removeClass(&#39; show&#39; ;)至少在iOS上有一些很好的淡出效果。

因为我已经混淆了几个问题,我将逐一澄清:

查找触发器:您可以按照建议使用自动运行或observeChanges,但最终都不需要这两个,因为始终会调用Meteor助手。 首先尝试:

<a href=# class='{{collapsed}}'

Template.genericCollapse.helpers({
  collapsed () {return "collapsed"},
})

当模板中的某些内容发生变化时,此助手中的代码将始终运行。如果data-1或data-2因任何原因发生变化,代码将被执行,因此这是我的触发器。

正确使用帮助:第一次尝试不对html执行任何操作,因为空格键{{collapsed}}不会更改其内容。虽然执行了辅助代码,但返回值不会改变,因此对html端没有影响。 为了查看任何更改,每次返回值必须不同。 第二次尝试:

Template.genericCollapse.helpers({
  collapsed () {return "collapsed " + Random.Id()},
})
像我已经说过的那样丑陋,但至少它为a设置了正确的等级。

摆脱&#34;显示&#34;:米歇尔来了:因为&#34;显示&#34;在div中由Bootstrap控制,你不能使用任何类型的空格键/助手来控制它 - 但是使用javascript。 第三次尝试:

Template.genericCollapse.helpers({
  collapsed () {
    $('.show').removeClass('show');
    return "collapsed " + Random.Id()},
})

这个有效!可能有必要缩小范围。显示&#39;如果其他元素有类&#34;显示&#34;存在,但这是要走的路。

Prettify:将Random.Id()作为一个类仍然很糟糕。因此,让我们像处理div一样对待。另外,我们应该使用&#34; uniqueId&#34;作为两者的标识符。 第四次尝试:

Template.genericCollapse.helpers({
  collapsed () {
    $('[data-target="#uniqueId"]').addClass('collapsed');
    $('#uniqueId').removeClass('show');
    return "collapsed"},
})

让它闪亮:帮助器{{collapsed}}不再需要返回任何值,这都是使用javascript完成的。我们只需要触发器功能,所以这是最终的代码:

<template name="genericCollapse">
  {{data-1}}
  <a href=# class='collapsed' data-toggle='collapse' {{hook}}
     data-target='#uniqueId'>Show/hide data-2</a>
  <div class='collapse' id='uniqueId'>
    {{data-2}}
  </div>
</template>

Template.genericCollapse.helpers({
  hook () {
    $('[data-target="#uniqueId"]').addClass('collapsed');
    $('#uniqueId').removeClass('show');
  }
})

像魅力一样。

答案 3 :(得分:0)

你可以通过将类从一个帮助器返回到元素来做到这一点:

<强>模板:

<template name="genericCollapse">
  {{data-1}}
  <a href=# class={{isCollapsed}} data-toggle='collapse'
     data-target='#uniqueId'>Show/hide data-2</a>
...
...
</template>

<强>助手:

Template.genericCollapse.helpers({

isCollapsed: function(){

    if()// logic to check if it needs to be collapsed
       return "collapsed"
    else
       return "collapse"
    }
});