试图调试一些东西。在我们的客户端上,我们进行了Accounts.createUser()
调用,其中包含一个类似于以下内容的回调:
function(err) {
if (err) {
Session.set('entryError', err.reason);
}
else {
return Router.go('/');
}
}
使用此设置,正常注册(即没有错误)正常工作。但是,如果出现错误,模板将被销毁,创建和呈现两次。我找到了this question,然后寻找潜在的反应变量来触发这个。我唯一能发现两个模板销毁/创建/渲染调用之间的变化是Meteor.loggingIn()
(包括会话变量)。这似乎并没有造成这种情况,因为当我删除对它的所有引用及其依赖关系时,问题仍然存在。
任何指针?
ETA:根据以下要求。
signUpPage.html:
<template name='signUpPage'>
<main id="signUpPage">
<h1 class="accountsTitle">Sign Up</h1>
<p id="signInPrompt">If you already have an account <a href="/sign-in">sign in</a>.</p>
<form id='signUpForm'>
{{> entryError}}
<div class="form-group">
<label for="usernameInput">Username</label>
<input id="usernameInput" type="string" class="form-control" value=''>
</div>
<div class="form-group">
<label for="emailInput">Email Address</label>
<input id="emailInput" type="email" class="form-control" value=''>
</div>
<div class="form-group">
<label for="passwordInput">Password</label>
<input id="passwordInput" type="password" class="form-control" value=''>
</div>
<div class="form-group">
<label for="confirmPasswordInput">Confirm Password</label>
<input id="confirmPasswordInput" type="password" class="form-control" value=''>
</div>
<div class="form-group">
<label for="signupCodeInput">Signup Code</label>
<input id="signupCodeInput" class="form-control" value=''>
</div>
<button type="submit" class="btn btn-primary btn-block">Sign up</button>
</form>
</main>
</template>
signUpPage.js
Template.signUpPage.events({
'submit #signUpForm': function(event, template) {
event.preventDefault();
// Get the input values from the form
var username = template.find("#usernameInput").value.trim();
var email = template.find("#emailInput").value.trim();
var signupCode = template.find("#signupCodeInput").value;
var password = template.find("#passwordInput").value;
var confirmPassword = template.find("#confirmPasswordInput").value;
// Log the signup attempt
var signupAttempt = {'type':'signup', 'username':username, 'email':email, 'password':password, 'signupCode':signupCode};
Logins.insert(signupAttempt);
// Validate username presence
if (!username.length)
return Session.set('entryError', 'Username is required');
// Validate email presence
if (!email.length)
return Session.set('entryError', 'Email address is required');
// Validate password
var passwordErrors = validatePassword(password, confirmPassword);
if (passwordErrors.length) {
var errorsString = passwordErrors.join("\r\n");
Session.set('entryError', errorsString);
return;
}
// Validate signup code
if (!signupCode.length)
return Session.set('entryError', 'Signup code is required');
Meteor.call('createAccount', username, email, password, signupCode, function(err, data) {
if (err) {
Session.set('entryError', err.reason);
return;
}
else {
Meteor.loginWithPassword(username, password);
return Router.go('/');
}
});
}
});
Template.signUpPage.destroyed = function () {
Session.set("entryError", null);
};
Template.signUpPage.created = function() {
document.title = "Grove OS | Sign Up";
};
以下是使用entryError
的js文件:
Template.signInPage.events({
'click #signInButton': function(evt, template) {
evt.preventDefault();
// Making lowercase here, check on the server should be case insensitive though
var email = template.find('#emailInput').value.trim().toLowerCase();
var password = template.find('#passwordInput').value;
if (!email.length)
return Session.set('entryError', 'Email is blank');
if (!password.length)
return Session.set('entryError', 'Password is blank');
var loginAttempt = {'type':'login', 'email':email, 'date':new Date()};
return Meteor.loginWithPassword(email, password, function(error) {
if (error) {
loginAttempt.status = 'error';
Logins.insert(loginAttempt);
return Session.set('entryError', error.reason);
} else{
loginAttempt.status = 'success';
Logins.insert(loginAttempt);
return Router.go("/");
}
});
},
'click #signUpButton': function(evt, template) {
evt.preventDefault();
Router.go("signUpRoute");
},
'click #forgotPasswordButton': function(evt, template) {
evt.preventDefault();
Router.go("forgotPasswordRoute");
}
});
Template.signInPage.destroyed = function () {
Session.set("entryError", null);
};
Template.signInPage.created = function() {
document.title = "Grove OS | Sign In";
};
-
Template.resetPasswordPage.helpers({
error: function() {
return Session.get('entryError');
}
});
Template.resetPasswordPage.events({
'submit #resetPasswordForm': function(event, template) {
event.preventDefault();
var password = template.find('#passwordInput').value;
var confirmPassword = template.find('#confirmPasswordInput').value;
// Validate password
var passwordErrors = validatePassword(password, confirmPassword);
if (passwordErrors.length) {
var errorsString = passwordErrors.join("\r\n");
return Session.set('entryError', errorsString);
} else {
return Accounts.resetPassword(Session.get('resetToken'), password, function(error) {
if (error) {
return Session.set('entryError', error.reason || "Unknown error");
} else {
Session.set('resetToken', null);
return Router.go("/");
}
});
}
}
});
Template.resetPasswordPage.created = function () {
document.title = "Grove OS | Reset Password";
};
-
Template.forgotPasswordPage.events({
'submit #forgotPasswordForm': function(event, template) {
event.preventDefault();
var email = template.find("#forgottenEmail").value;
if (!email.length) {
return Session.set('entryError', 'Email is required');
} else {
return Accounts.forgotPassword({
email: email
}, function(error) {
if (error)
return Session.set('entryError', error.reason);
else
return Router.go("/");
});
}
}
});
Template.forgotPasswordPage.created = function () {
document.title = "Grove OS | Forgot Password";
};
- 路由器代码(由2个文件组成):
//--------------------------------------------------------------
// Global Configuration
Router.configure({
layoutTemplate: 'appBody',
notFoundTemplate: 'notFoundPage',
loadingTemplate: 'loadingPage',
yieldTemplates: {
'appHeader': {to: 'header'},
'appFooter': {to: 'footer'}
}
});
// Have to sign in to access all application pages
Router.onBeforeAction(function() {
console.log("Global router onBeforeAction calle");
// if (!Meteor.loggingIn() && !Meteor.user()) {
if(!Meteor.user()){
this.redirect('/sign-in');
}
this.next();
}, {
// whitelist which routes you don't need to be signed in for
except: [
'signUpRoute',
'signInRoute',
'forgotPasswordRoute',
'signOutRoute',
'resetPasswordRoute',
'pageNotFoundRoute'
]
});
// Subscriptions application-wide
Router.waitOn(function() {
if (Meteor.loggingIn() || Meteor.user())
return Meteor.subscribe("userGroups");
});
//--------------------------------------------------------------
// Root route
Router.route('landingRoute', {
path: '/',
onBeforeAction: function(){
console.log("other global one is being called");
// if (!Meteor.loggingIn() && !Meteor.user()){
if(!Meteor.user()){
this.redirect('/sign-in');
}else{
this.redirect('/grove/dashboard');
}
this.next();
}
});
//--------------------------------------------------------------
// Static Routes
Router.route('/glossary', {
path: '/glossary',
template: 'glossaryPage'
});
Router.route('/eula', {
path: '/eula',
template: 'eulaPage'
});
Router.route('/privacy', {
path: '/privacy',
template: 'privacyPage'
});
Router.route('/about', {
path: '/about',
template: 'aboutPage'
});
Router.route("signUpRoute", {
path: "/sign-up",
template: "signUpPage"
});
Router.route("signInRoute", {
path: "/sign-in",
template: "signInPage"
});
Router.route('signOutRoute', {
path: '/sign-out',
template: "signOutPage",
onBeforeAction: function() {
Meteor.logout();
Router.go('/');
this.next();
}
});
Router.route("forgotPasswordRoute", {
path: "/forgot-password",
template: "forgotPasswordPage",
});
Router.route('resetPasswordRoute', {
path: 'reset-password/:resetToken',
template: "resetPasswordPage",
data: function() {
Session.set('resetToken', this.params.resetToken);
return ;
}
});
Router.route("404Route", {
path: "/page-not-found",
template: "notFoundPage",
});
Router.route("dashboardRoute", {
path: "/dashboard",
template: "dashboardPage"
});
Router.route('createShrub', {
path: '/tools/createShrub',
template: 'upsertShrubPage',
waitOn: function(){
},
data: function () {
},
});
// TODO figure out how to dynamically render templates
// based on if the slug is a group, user, or nothing
// and also conditionally subscribe
Router.route('profileRoute', {
path: '/:ownerSlug',
template: 'myProfilePage'
});
Router.route('groveRoute', {
path: '/:ownerSlug/:groveSlug',
template: 'grovePage',
data: function () {
return Groves.findOne({ slug: this.params.groveSlug });
},
});
Router.route('shrubRoute', {
path: '/:ownerSlug/:groveSlug/:shrubSlug',
template: 'shrubStaticPage',
data: function() {
Session.set("currentShrub", this.params.shrubSlug);
return ShrubTemplates.findOne({ slug: this.params.shrubSlug });
},
action: function() {
if (this.ready())
this.render();
else
this.render('loadingHolder');
}
});
答案 0 :(得分:0)
嗯,事实证明,作为路由器的一部分,有这个功能:
Router.waitOn(function() {
if (Meteor.loggingIn() || Meteor.user())
return Meteor.subscribe("userGroups");
});
Meteor.loggingIn()
中的更改导致此功能运行,我们看到我们的加载页面会短暂显示。我们更改了if
语句,使其不再包含Meteor.loggingIn()
项检查。有点尴尬,真的 - 我发誓我之前看过那条线。不知道在我的思考过程中发生了什么,想念这个。至少现在我对铁路由器有了更好的了解。