流星和铁路由器的分页不能重新渲染

时间:2015-10-27 10:01:56

标签: meteor iron-router

我真的很难理解这里发生了什么。我有一个模板

<template name="gallery">
  <div>
    <a href="/">1</a><a href="/gallery/2">2</a><a href="/gallery/3">3</a>
  </div>
  {{#each art}}
    {{name}} 
  {{/each}}
</template>

然后我有这样的路线

Router.map(function() {
  this.route('/', {
    template: 'gallery',
    data: function() {
      var page = 1;
      return {
        page: page,
      };
    },
  });
  this.route('/gallery/:_page', {
    template: 'gallery',
    data: function() {
      var page = parseInt(this.params._page);
      return {
        page: page,
      };
    },
  });
});

关注this article我正在使用像这样的模板订阅

  var G_PAGE_SIZE = 10;

  Template.gallery.onCreated(function() {
    var instance = this;
    var route = Router.current();
    instance.loaded  = new ReactiveVar(0);

    instance.autorun(function() {
      var pageId = parseInt(route.params._page);
      var page = pageId - 1;
      var skip = page * G_PAGE_SIZE;

      var subscription = instance.subscribe('artForGrid', skip, G_PAGE_SIZE);
      if (subscription.ready()) {
        instance.loaded.set(1);
      }
    });

    instance.art = function() {
      return Art.find({});
    };
  });

  Template.gallery.helpers({
    art: function() {
      return Template.instance().art();
    },
  });

它有效,但是当我点击其中一个更改路线的链接时,页面不会重新渲染

所以... some other answer on here表示,因为通过路由器的路线上的数据变化与模板之间没有反应连接。

所以我尝试使用route.state作为ReactiveDict(不知道它来自哪里)。如果它是铁的一部分:路由器或者它是反应变量的一部分

无论如何我将代码更改为

Router.map(function() {
  this.route('/', {
    template: 'gallery',
    data: function() {
      var page = 1;
      this.state.set('page', page);  // <------------ADDED
      return {
        page: page,
      };
    },
  });
  this.route('/gallery/:_page', {
    template: 'gallery',
    data: function() {
      var page = parseInt(this.params._page);
      this.state.set('page', page);  // <------------ADDED
      return {
        page: page,
      };
    },
  });
});

onCreated

  Template.gallery.onCreated(function() {
    var instance = this;
    var route = Router.current();
    instance.loaded  = new ReactiveVar(0);

    instance.autorun(function() {
      var pageId = route.state.get('page'); // <--------- CHANGED
      var page = pageId - 1;
      var skip = page * G_PAGE_SIZE;

      var subscription = instance.subscribe('artForGrid', skip, G_PAGE_SIZE);
      if (subscription.ready()) {
        instance.loaded.set(1);
      }
    });

    instance.art = function() {
      return Art.find({});
    };
  });

  Template.gallery.helpers({
    art: function() {
      return Template.instance().art();
    },
  });

除了有时候,它不会起作用。为了调试,我在路由中添加了console.log

Router.map(function() {
  this.route('/', {
    template: 'gallery',
    data: function() {
      var page = 1;
      this.state.set('page', page);
      console.log("/root");  // <------------ADDED
      return {
        page: page,
      };
    },
  });
  this.route('/gallery/:_page', {
    template: 'gallery',
    data: function() {
      var page = parseInt(this.params._page);
      this.state.set('page', page);
      console.log("/gallery/" + page);  // <------------ADDED
      return {
        page: page,
      };
    },
  });
});

突然间它开始工作了!???!@!?我删除了console.logs并停止了

我还尝试在没有console.logs的情况下添加动作

Router.map(function() {
  this.route('/', {
    template: 'gallery',
    data: function() {
      var page = 1;
      this.state.set('page', page);
      return {
        page: page,
      };
    },
    action: function() {              // <- added
      var page = 1;                   // <- added
      this.state.set('page', page);   // <- added
      this.render();                  // <- added
    },                                // <- added
  });
  this.route('/gallery/:_page', {
    template: 'gallery',
    data: function() {
      var page = parseInt(this.params._page);
      this.state.set('page', page);
      return {
        page: page,
      };
    },
    action: function() {                      // <- added
      var page = parseInt(this.params._page); // <- added
      this.state.set('page', page);           // <- added
      this.render();                          // <- added
    },                                        // <- added
  });
});

这也不起作用。

更新

所以使用Router.current().data().???似乎可以使它工作。现在就是这个

Router.map(function() {
  this.route('/', {
    template: 'gallery',
    data: function() {
      var page = 1;
          // <--- removed this.state() stuff
      return {
        page: page,
      };
    },
         // <---- removed action stuff
  });
  this.route('/gallery/:_page', {
    template: 'gallery',
    data: function() {
      var page = parseInt(this.params._page);
          // <--- removed this.state() stuff
      return {
        page: page,
      };
    },
         // <---- removed action stuff
  });
});

辅助

  Template.gallery.onCreated(function() {
    var instance = this;
    instance.loaded  = new ReactiveVar(0);

    instance.autorun(function() {
      var route = Router.current();    // <----- Moved from 3 lines up
      var pageId = route.data().page;  // <--------- CHANGED
      var page = pageId - 1;
      var skip = page * G_PAGE_SIZE;

      var subscription = instance.subscribe('artForGrid', skip, G_PAGE_SIZE);
      if (subscription.ready()) {
        instance.loaded.set(1);
      }
    });

    instance.art = function() {
      return Art.find({});
    };
  });

  Template.gallery.helpers({
    art: function() {
      return Template.instance().art();
    },
  });

不知道现在是否正确,或者我是否像使用console.log版本一样幸运

1 个答案:

答案 0 :(得分:1)

我的猜测是你的autorun函数没有被重新运行,因为你没有使用任何反应变量。我不确定Router.current()Router.current().data()是否具有反应性,但如果他们不反应,那么这对我来说就是明确的问题。要对此进行测试,请尝试在autorun函数中添加一些控制台日志记录。

现在,我会提出一些可能对您有用的修订。

路由代码

重定向到'/'网址'/gallery/1',以便您可以重复使用路由代码

Router.route('/', function(){
    this.redirect('/gallery/1');
});

将数据对象中的页码发送到模板非常重要,这样我们就可以在autorun函数中使用此对象

Router.route('/gallery/:_page', {
    template: 'gallery',
    data: function() {
        return {
            page: this.params._page,
        };
    }
});

此外,除非您尝试在路由代码中重新路由或处理该异常,否则您不需要使用parseInt方法。

图库onCreatedhelpers

Meteor提供了一个Template.subscriptionsReady帮助程序,因此您不必手动检查订阅是否已加载,除非您真的需要它。这是Template.subscriptionsReady documentation

以下是使用onCreated对象的template.data方法的简化版本,该对象是由上面的路由代码构建的。使用autorun包装器非常重要,以便在路由器更改template.data时重新运行。

var G_PAGE_SIZE = 10;

Template.gallery.onCreated(function() {
    var instance = this;

    instance.autorun(function() {
        // access the data object built by your route code
        var pageId = instance.data.page;  

        var page = pageId - 1;
        var skip = page * G_PAGE_SIZE;

        instance.subscribe('artForGrid', skip, G_PAGE_SIZE);
    });

});

使用template.helpers方法定义对您的被动数据源的访问权限。

Template.gallery.helpers({
    art: function() {
        return Art.find({});
    }
});

注意:无需在onCreatedtemplate.helpers

中定义帮助程序