【问题标题】:Meteor.autorun() not working on client when insert occures插入发生时 Meteor.autorun() 在客户端上不起作用
【发布时间】:2014-03-26 06:18:16
【问题描述】:

我已经在里面敲了两天的头。

我正在创建一个搜索引擎,正在使用 Meteor 框架动态创建查询,查询工作正常,当我搜索时,我可以将 UI(在我的案例中为表)与动态数据查询输出重新绑定。

但是,如果数据对象发生插入/更新/删除操作

并且 UI(html 表格)没有更新。

这意味着当数据对象改变时模板不会重新渲染。

Template.search.rendered = function () {


   Meteor.autorun(function() {
        alarmsData = Alarms.find(getSearchSelector($('#searchTxt').val(), $('#startTimeTxt').val(), $('#endTimeTxt').val())).fetch()
        console.log("rendered")
        //alarmsData = Alarms.find({},{sort: {timestamp: "desc"} }).fetch();
        searchControls(alarmsData)
        getConsole(alarmsData, ".console")
        $('#badge').html(alarmsData.length)
   })

}

get 控制台函数只是从搜索中读取数组并创建一个 html 表(这工作正常)

至于开始,我正在创建一个简单的查询作为我的搜索的默认值。然后在用户更改搜索条件时更改此查询。我可以注意到只有第一个数据对象实例被保留并跟踪更改,所以如果第二个搜索条件位于第一个搜索条件内,它正在更新 UI,如果没有任何事情发生

我使用过 Meteor.autorun(function(){}) 函数,但是我使用 console.log 跟踪了它的执行情况,当我在数据库中为同一个集合插入数据时,我可以看到它没有执行。

【问题讨论】:

    标签: meteor


    【解决方案1】:

    一,我相信你正在尝试使用Deps.autorun。此外,您的自动运行中似乎没有任何依赖于反应源的内容。由于alarmsData 正在拍摄数据快照,因此它不会关心警报何时发生数据更改。

    其次,我可能会通过重定向来解决这个问题。我会编译我的数据,并重定向到同一页面,允许服务器为我处理查询。这很容易让您在参数中使用预填充查询从其他任何地方跳转到此页面(因为路由会处理它),并且还可以在搜索发生时对导航栏进行视觉更改(就像所有其他搜索引擎一样)。您可以在单击按钮时执行以下操作:

    var query = {},
        path;
    
    query.text = encodeURIComponent($('#searchTxt').val()),
    query.start = encodeURIComponent($('#startTimeTxt').val()),
    query.end = encodeURIComponent($('#endTimeTxt').val()),
    
    // redirect to current path
    path = Router.routes[Router.current().route.name].path({}, {
        query: query
    });
    
    Router.go( path );
    

    在您的路由器中,您只需将查询传递到您的服务器并作为数据对象路由(假设您使用的是iron-router):

    this.route( "search", {
        path: "/search",
        waitOn: function() {
            return [
                Meteor.subscribe( "searchAlarms", _.omit( this.params, "hash" ) ),
            ]
        },
        data: function () {
            return { "query": _.omit( this.params, "hash" ) };
        }
    });
    

    这不仅会为您提供用于搜索的查询数据(在您的模板中),而且服务器现在可以为您处理搜索!您的警报数据现在包含显示给用户所需的所有文档,您不再需要订阅所有警报。这也很棒,因为它是自动反应的。因此,如果新警报与您的查询过滤器匹配,它将自动传递给客户端并显示给用户,而无需设置任何额外的依赖项/自动运行。

    但请注意,如果您在其他地方订阅警报,您仍然需要在客户端进行过滤。

    【讨论】:

      【解决方案2】:

      多么奇怪的流星代码……

      • 一旦您将呈现搜索模板,就会调用“呈现”代码方法代码
      • getSearchSelector($('#searchTxt').val() 不是响应式的,我的建议是使用会话变量将搜索条件放入其中,并使用同一会话将查找参数注入其中。

      您是否正在寻找显示所有警报数据?

      function getAlarms()
      {
          var text = Session.get("text");
          var from = Session.get("start");
          var to   = Session.get("end");
          var filter = getSearchSelector(text, from, to);
          return Alarms.find(filter);
      }
      
      Template.search.alarms = function () {
          return getAlarms();
      }
      
      Template.search.alarmsCount = function () {
          return getAlarms().count();
      }
      
      Template.search.events({
          'keypress input[name=text]' : function(e,o)
          {
              var val = $("input[name= text]").val()
              Session.set("text", val);
          },
          'keypress input[name=start]' : function(e,o)
          {
              var val = $("input[name=start]").val()
              Session.set("start", val);
          },
          'keypress input[name=end]' : function(e,o)
          {
              var val = $("input[name=end]").val()
              Session.set("end", val);
          }
      });
      

      // 你的模板看起来像:

      <template name="search">
          Search alarms
          <input type="text" name="text" placeholder="Enter your text here…"/>
          <input type="text" name="start" placeholder="start time"/>
          <input type="text" name="end" placeholder="end time/>
      
          There is {{alarmsCount}} alarms(s);
      
          {{#each alarms}}
          Alarm object: {{.}} 
          {{/each}}
      </template>
      

      【讨论】:

        【解决方案3】:

        我猜它通过使用 Session.set & get 解决它,并自动订阅 Serevr 并发送动态查询。

        检查以下代码

        Template.zConsole.rendered = function () {

            Session.set("obj", getSearchSelector($('#searchTxt').val(), $('#startTimeTxt').val(), $('#endTimeTxt').val()))
        
            Deps.autorun(function (){
                Meteor.subscribe("dynamicAlarms", Session.get("obj"))
                console.log("Count from AutoRun ==> " + Alarms.find(Session.get("obj")).count())
            })
        
        }
        

        在服务器上

        Meteor.publish('dynamicAlarms',function (searchObj) {
            return Alarms.find(searchObj)
        })
        

        & 它可以用更少的代码完美运行。

        【讨论】:

          猜你喜欢
          • 2012-06-13
          • 1970-01-01
          • 2012-11-13
          • 2015-02-09
          • 2020-12-25
          • 1970-01-01
          • 1970-01-01
          • 2017-06-04
          • 1970-01-01
          相关资源
          最近更新 更多