在DOM被反应模板数据更改后,Meteor调用JS

时间:2015-01-21 14:37:06

标签: javascript twitter-bootstrap events dom meteor

我正试图在一个更大的项目中考虑这个方法但是已经把这个小例子放在一起,希望找到一个解决方案..

通过创建一个新的流星项目(使用meteor 1.0.3.1)并添加mizzao:bootstrap-3并使用以下文件来组合这个例子:

的test.html

<head>
  <title>test</title>
</head>

<body>
  <div class="container-fluid">
    <div class="row">
      {{> example}}
    </div>
    {{> controls}}
  </div>
</body>

<template name="example">
  <div class="col-xs-{{zoom}}">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title"><span data-toggle="tooltip" data-placement="auto" title="Some text that will appear in the tooltip (which should be centered above or below this span) when hovering over the this span">Text that can spill out</span></h3>
      </div>
      <div class="panel-body">
        <p>Foo</p>
      </div>
    </div>
  </div>
</template>

<template name="controls">
  <button id="in">+</button>
  <button id="out">-</button>
</template>

test.css

.panel-title > span {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.panel-title div.tooltip {
  white-space: initial;
}

test.js

if (Meteor.isClient) {
  var minZoom = 1;
  var maxZoom = 4;
  Session.setDefault('zoom', 4);

  Template.example.helpers({
    zoom: function () {
      return Session.get('zoom');
    }
  });

  Template.controls.events({
    'click button': function(event) {
      switch(event.currentTarget.id) {
        case 'in':
          if (Session.get('zoom') < maxZoom)
            Session.set('zoom', Session.get('zoom') + 1);
          break;
        case 'out':
          if (Session.get('zoom') > minZoom)
            Session.set('zoom', Session.get('zoom') - 1);
          break;
      }
    }
  })

  test = function() {
    $('.panel-heading').each(function(index) {
      var h3 = $(this).find('h3');
      var span = $(this).find('span');
      span.width('initial');
      if (span.width() > h3.width()) {
        span.width('100%');
      }
    });
    $('[data-toggle="tooltip"]').tooltip();
  }

  Template.example.rendered = function() {
    test();
  }
}

希望很明显(ish)我正在努力实现的是跨度(在悬停时切换到工具提示)设置为与h3相同的宽度,否则跨度将超过h3的宽度 - 或者如果h3较大,则将跨度设置为默认值(内联/初始宽度)。这样做的原因是,当初始化工具提示时,工具提示应显示在范围文本的上方(或下方)的中心。 在渲染模板时调用test()按预期工作(您可以更改'zoom'会话的默认值以在首次加载页面时更改面板的宽度 - 我一直使用1和4来测试。 但是,当DOM因为单击+或 - 按钮时发生的被动会话变量'zoom'更改而更新时,我需要调用test()。发生这种情况时,面板类col-md-#changes会改变其中#是缩放会话变量的值。

总而言之,DOM发生了变化,但这不是对我直接进行的JavaScript调用的响应,也不是由于订阅数据的变化,所以我不相信我可以使用Tracker.afterFlush回调。 由于缩放助手必须在更新DOM之前返回,我无法看到一种方法来调用由任何特定事件触发的'test()'并且添加一些东西到点击按钮会发生得太早,是否有人有任何想法?

同样根据我的读法,Mutation Observers还没有被广泛支持,所以这可能不是一个选择。

由于

2 个答案:

答案 0 :(得分:2)

如果我做对了,你实际上是在更改一个会话变量,并希望在它发生变化时进行回调?如果这是正确的,那么将该变量包装在自动运行函数中将在每次变量更改时执行它。

此外,如果仍然存在赛车问题,您可以在调用test()之前使用带有小延迟的setTimeout。

Tracker.autorun(function () {
  Session.get('zoom');
  test();
});

答案 1 :(得分:1)

发布到Meteor论坛后,这是我无耻的回答。

在您进行更改以引起被动更改后,请将您的javascript置于Tracker.afterFlush回调中。

http://docs.meteor.com/#/full/tracker_afterflush