Javascript 流星:元素的力渲染

Javascript 流星:元素的力渲染,javascript,meteor,meteor-blaze,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}}

我的应用程序中多次使用了一个通用模板:

<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会同时更改(使用会话变量)。但是,如果模板已经在屏幕上,则只有data-1和data-2在更改,但div的折叠状态(显然)保持不变。如果它以前打开过,它将保持打开状态

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

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

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

您可以通过meteor方法从助手处将类返回到元素,如下所示:

模板:

<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"
    }
});

看起来你在和bootstrap搏斗。单击链接时,
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-1
data-2
。如果您的
data-1
data-2
是执行某些计算的助手,那么您可能希望使用基于反应变量的
跟踪器来实现这一点。

@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-1
data-2
更改,此功能都将重新运行

非常感谢您的帮助

@Michel Floyd让我意识到我的问题不是由任何与Meteor有关的事情引起的,而是由bootstrap引起的

@弗雷德·斯塔克为解决方案添加了一个很好的变体,他使用了更像流星风格的自动运行,并使用了.collapse('hide')而不是.removeClass('show'),至少在iOS上提供了一些不错的淡出效果

由于我混淆了几个问题,我将逐一澄清:

找到一个触发器:您可以按照建议使用autorun或observeChanges,但最终这两种方法都不是必需的,因为Meteor助手总是被调用。 第一次尝试:

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

Template.genericCollapse.helpers({
  collapsed () {return "collapsed"},
})
我已经说过了,很难看,但至少它为a设置了正确的类

去掉“show”:米歇尔来了:因为div中的“show”是由引导控制的,所以你不能用任何类型的空格键/助手来控制它,只能用javascript。 第三次尝试:

Template.genericCollapse.helpers({
  collapsed () {
    $('.show').removeClass('show');
    return "collapsed " + Random.Id()},
})
这管用!如果存在类为“show”的其他元素,可能有必要缩小“.show”的范围,但这是解决方法

美化:将Random.Id()作为一个类仍然很糟糕。因此,让我们以处理div的相同方式来处理a。此外,我们应该使用“uniqueId”作为两者的标识符。 第四次尝试:

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');
  }
})

{{data-1}}
{{data-2}}
Template.genericCollapse.helpers({
钩子(){
$(“[data target=“#uniqueId”]”)。addClass('collapsed');
$('uniqueId').removeClass('show');
}
})

这是会话/反应式变量的正确答案。
<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');
  }
})