2015-10-27 1 views
0

Я действительно пытаюсь понять, что здесь происходит. У меня есть шаблонПагинация с метеорным и железным маршрутизатором не перерисовывается

<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(); 
    }, 
    }); 

Это работает, но когда я нажимаю один из ссылки, изменяющие маршрут, страница не перерисовывается

So ... 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

Мое предположение является то, что ваша функция autorun не будет повторно запущена, потому что вы не используете какие-либо реактивные переменные. Я не уверен, что Router.current() или Router.current().data() реагируют, но если это не так, то это ясно объясняет мне проблему. Чтобы проверить это, попробуйте помещать некоторые записи в консоль в вашу функцию autorun.

Теперь я предложил некоторые изменения, которые могут сработать для вас.

Routing код

Перенаправление на '/' URL в '/gallery/1', так что вы можете повторно использовать маршрутизацию кода

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

Отправка номер страницы в объекте данных в шаблоне важно, чтобы мы могли используйте этот объект в нашей autorun функции

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

Кроме того, вам не нужно использовать метод parseInt, если вы не пытаетесь перенаправить или обработать это исключение в коде маршрутизации.

Галерея onCreated и helpers

Существует 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({}); 
    } 
}); 

Примечание: Не требуется, чтобы определить ваш помощник в onCreated и template.helpers

+0

Спасибо за подробные предложения. Они были супер полезны – gman

+0

instance.data не реагирует, ваш код не работает. изменить с помощью параметра Router.current(). Data() – Dayd