MeteorJS:集合.多次寻找火灾,而不是一次



我有一个应用程序,当你从下拉列表中选择一个行业时,一个集合被更新,其中属性等于所选行业。

JavaScript:

Template.selector.events({
  'click div.select-block ul.dropdown-menu li': function(e) {
    var selectedIndex = $(e.currentTarget).attr("rel");
    var val = $('select#industryPicker option:eq(' + selectedIndex + ')').attr('value');
    var oldVal = Session.get('currentIndustryOnet');
    if(val != oldVal) {
      Session.set('jobsLoaded', false);
      Session.set('currentIndustryOnet', val);
      Meteor.call('countByOnet', val, function(error, results){
        if(results > 0) {
          Session.set('jobsLoaded', true);
        } else {
          getJobsByIndustry(val);
        }
      });
    }
  }
});
var getJobsByIndustry = function(onet) {
  if(typeof(onet) === "undefined")
      alert("Must include an Onet code");
  var params = "onet=" + onet + "&cn=100&rs=1&re=500";
  return getJobs(params, onet);
}
var getJobs = function(params, onet) {
  Meteor.call('retrieveJobs', params, function(error, results){
    $('job', results.content).each(function(){
      var jvid = $(this).find('jvid').text();
      var job = Jobs.findOne({jvid: jvid});
      if(!job) {
        options = {}
        options.title = $(this).find('title').text();
        options.company = $(this).find('company').text();
        options.address = $(this).find('location').text();
        options.jvid = jvid;
        options.onet = onet;
        options.url = $(this).find('url').text();
        options.dateacquired = $(this).find('dateacquired').text();
        var id = createJob(options);
        console.log("Job Created: " + id);
      }
    });
    Session.set('jobsLoaded', true);
  });
}
Template.list.events({
  'click div.select-block ul.dropdown-menu li': function(e){
    var selectedIndex = $(e.currentTarget).attr("rel");
    var val = $('select#perPage option:eq(' + selectedIndex + ')').attr('value');
    var oldVal = Session.get('perPage');
    if(val != oldVal) {
      Session.set('perPage', val);
      Pagination.perPage(val);
    }
  }
});
Template.list.jobs = function() {
  var jobs;
  if(Session.get('currentIndustryOnet')) {
    jobs = Jobs.find({onet: Session.get('currentIndustryOnet')}).fetch();
    var addresses = _.chain(jobs)
                .countBy('address')
                .pairs()
                .sortBy(function(j) {return -j[1];})
                .map(function(j) {return j[0];})
                .first(100)
                .value();
    gmaps.clearMap();
    $.each(_.uniq(addresses), function(k, v){
      var addr = v.split(', ');
      Meteor.call('getCity', addr[0].toUpperCase(), addr[1], function(error, city){
        if(city) {
          var opts = {};
          opts.lng = city.loc[1];
          opts.lat = city.loc[0];
          opts.population = city.pop;
          gmaps.addMarker(opts);
        }
      });
    })
    return Pagination.collection(jobs);
  } else {
    jobs = Jobs.find()
    Session.set('jobCount', jobs.count());
    return Pagination.collection(jobs.fetch());
  }
}

Template.list.jobs中,如果您使用console.log(addresses),则调用4次不同的次数。浏览器控制台如下所示:

(2) 100
(2) 100

为什么会多次触发?

正如@musically_ut所说,这可能是因为您的会话数据。

基本上你必须区分响应性数据源和非响应性数据源。

非响应式是标准的javascript,没什么特别的。

然而,响应式数据源是由Meteor监控的,当其中一个被更新(插入、更新、删除,你能想到的)时,Meteor将再次执行使用该数据源的所有部分。默认的响应数据源是:集合和会话。你也可以创建自己的

所以当你更新你的会话属性时,它将再次执行所有使用这个数据源的助手方法。

关于渲染,页面在Meteor <0.8,现在火焰不再是这种情况了。

下面是一个快速示例,以便更好地理解:

模板优先

<head>
  <title>test</title>
</head>
<body>
  {{> hello}}
</body>
<template name="hello">
    <h1>{{getSession}}</h1>
    <h1>{{getNonReactiveSession}}</h1>
    <h1>{{getCollection}}</h1>
    <input type="button" name="session" value="Session" />
    <input type="button" name="collection" value="Collection" />
</template>

和客户端代码

if (Meteor.isClient) {
  CollectionWhatever = new Meteor.Collection;
  Template.hello.events({
    'click input[name="session"]': function () {
        Session.set('date', new Date());
    },
    'click input[name="collection"]': function () {
        CollectionWhatever.insert({});
      }
  });
    Template.hello.getSession = function () {
        console.log('getSession');
        return Session.get('date');
    };
    Template.hello.getNonReactiveSession = function () {
        console.log('getNonReactiveSession');
        var sessionVal = null;
        new Deps.nonreactive(function () {
            sessionVal = Session.get('date');
        });
        return sessionVal;
    };
    Template.hello.getCollection = function () {
        console.log('getCollection');
        return CollectionWhatever.find().count();
    };
    Template.hello.rendered = function () {
        console.log('rendered');
    }
}

如果你点击一个按钮,它将更新一个数据源,并且使用这个数据源的helper方法将再次执行。

除了非响应性会话,使用Deps.nonreactive你可以让Meteor忽略更新。

不要犹豫,添加日志到您的应用程序!

你可以读:

  • 反应
  • <
  • 依赖/gh>

最新更新