Mitrhil.js 条件路由和身份验证
Mitrhil.js conditional routing and authentication
我正在学习 javascript
和 mithril.js 1.1.6
。我正在写一个简单的网络应用程序,用户可以在其中登陆一个他可以登录的页面。已经登录的用户登陆了不同的页面。我正在尝试使用条件路由,这里是主要组件:
const m = require("mithril");
...
import Eventbus from './whafodi/eventbus.js';
import WelcomePage from './ui/welcome.js';
import User from './model/user.js';
var eventbus = new Eventbus();
function MyApp() {
return {
usrAuth: function() {
m.route(document.body, "/", {
"/": { view: () => m("p", "hello")}
})
},
usrNotAuth: function() {
m.route(document.body, "/", {
"/": { render: v => m(WelcomePage, eventbus) }
})
},
oninit: function(vnode) {
vnode.state.user = new User();
eventbus.subscribe({
type: "login",
handle: function(action) {
vnode.state.user.token = action.token;
console.log(JSON.stringify(vnode.state.user));
}
});
},
view: function(vnode) {
if(vnode.state.user.token) {
this.usrAuth();
} else {
this.usrNotAuth();
}
}
}
};
m.mount(document.body, MyApp);
MyApp
为主成分。它检查用户是否有令牌,然后 return 正确的 route
。这是负责让用户登录的组件:
const m = require("mithril");
const hellojs = require("hellojs");
function TopBar(node) {
var bus = node.attrs.eventbus;
function _login() {
hellojs('facebook').login({scope:'email'});
}
return {
oninit: function(vnode) {
hellojs.init({
facebook: XXXXXXX,
}, {
redirect_uri: 'http://localhost'
});
hellojs.on('auth.login', auth => {
var fbtoken = auth.authResponse.access_token;
m.request({
method:"POST",
url:"./myapp/login/fb/token",
data:auth.authResponse,
background: true
}).then(function(result){
console.log(result);
bus.publish({ type: "login", token: result.jwttoken });
m.route.set("/");
}, function(error){
console.log(error);
bus.publish({ type: "login", token: "" });
});
});
},
view: function(vnode) {
return m("div", [
m("button", { onclick: _login }, "Login")
]);
}
}
}
export default TopBar;
TopBar
组件出现在主组件中提到的 WelcomePage
组件中。 TopBar
呈现一个按钮并使用 hello.js
登录。它使用 EventBus
总线参数来告诉主要组件用户已登录(主要组件中有一个处理程序来更新用户模型)。一旦用户登录,事件就会被触发,主要组件会更新用户模型。好的。现在,如何触发主组件加载正确的路由?
我再次阅读了 mithril'docs,发现 RouteResolvers 完全符合我的需要。这是一个例子:
var App = (function() {
var login;
function isLoggedIn(component) {
if(login) {
return component;
} else {
m.route.set("/hey");
}
}
return {
oninit: function(vnode) {
EventBus.subscribe({
type: "login",
handle: function(action) {
console.log("incoming action: " + JSON.stringify(action));
login = action.value;
}
});
},
oncreate: function(vnode) {
Foo.eventbus = EventBus;
Bar.eventbus = EventBus;
Hey.eventbus = EventBus;
m.route(document.body, "/hey", {
"/foo": {
onmatch: function(args, requestedPath, route) { return isLoggedIn(Foo); }
},
"/bar": {
onmatch: function(args, requestedPath, route) { return isLoggedIn(Bar); }
},
"/hey": Hey
});
},
view: function(vnode) {
return m("div", "home..");
}
};
})();
Eventbus
用于让组件与App
通信。它们触发 App
可以处理的事件(登录类型事件)。我发现以 oncreate
方法显示的方式传递 Eventbus
很方便,我可以在每个组件的 oncreate
中使用 Eventbus
让组件触发事件。
我正在学习 javascript
和 mithril.js 1.1.6
。我正在写一个简单的网络应用程序,用户可以在其中登陆一个他可以登录的页面。已经登录的用户登陆了不同的页面。我正在尝试使用条件路由,这里是主要组件:
const m = require("mithril");
...
import Eventbus from './whafodi/eventbus.js';
import WelcomePage from './ui/welcome.js';
import User from './model/user.js';
var eventbus = new Eventbus();
function MyApp() {
return {
usrAuth: function() {
m.route(document.body, "/", {
"/": { view: () => m("p", "hello")}
})
},
usrNotAuth: function() {
m.route(document.body, "/", {
"/": { render: v => m(WelcomePage, eventbus) }
})
},
oninit: function(vnode) {
vnode.state.user = new User();
eventbus.subscribe({
type: "login",
handle: function(action) {
vnode.state.user.token = action.token;
console.log(JSON.stringify(vnode.state.user));
}
});
},
view: function(vnode) {
if(vnode.state.user.token) {
this.usrAuth();
} else {
this.usrNotAuth();
}
}
}
};
m.mount(document.body, MyApp);
MyApp
为主成分。它检查用户是否有令牌,然后 return 正确的 route
。这是负责让用户登录的组件:
const m = require("mithril");
const hellojs = require("hellojs");
function TopBar(node) {
var bus = node.attrs.eventbus;
function _login() {
hellojs('facebook').login({scope:'email'});
}
return {
oninit: function(vnode) {
hellojs.init({
facebook: XXXXXXX,
}, {
redirect_uri: 'http://localhost'
});
hellojs.on('auth.login', auth => {
var fbtoken = auth.authResponse.access_token;
m.request({
method:"POST",
url:"./myapp/login/fb/token",
data:auth.authResponse,
background: true
}).then(function(result){
console.log(result);
bus.publish({ type: "login", token: result.jwttoken });
m.route.set("/");
}, function(error){
console.log(error);
bus.publish({ type: "login", token: "" });
});
});
},
view: function(vnode) {
return m("div", [
m("button", { onclick: _login }, "Login")
]);
}
}
}
export default TopBar;
TopBar
组件出现在主组件中提到的 WelcomePage
组件中。 TopBar
呈现一个按钮并使用 hello.js
登录。它使用 EventBus
总线参数来告诉主要组件用户已登录(主要组件中有一个处理程序来更新用户模型)。一旦用户登录,事件就会被触发,主要组件会更新用户模型。好的。现在,如何触发主组件加载正确的路由?
我再次阅读了 mithril'docs,发现 RouteResolvers 完全符合我的需要。这是一个例子:
var App = (function() {
var login;
function isLoggedIn(component) {
if(login) {
return component;
} else {
m.route.set("/hey");
}
}
return {
oninit: function(vnode) {
EventBus.subscribe({
type: "login",
handle: function(action) {
console.log("incoming action: " + JSON.stringify(action));
login = action.value;
}
});
},
oncreate: function(vnode) {
Foo.eventbus = EventBus;
Bar.eventbus = EventBus;
Hey.eventbus = EventBus;
m.route(document.body, "/hey", {
"/foo": {
onmatch: function(args, requestedPath, route) { return isLoggedIn(Foo); }
},
"/bar": {
onmatch: function(args, requestedPath, route) { return isLoggedIn(Bar); }
},
"/hey": Hey
});
},
view: function(vnode) {
return m("div", "home..");
}
};
})();
Eventbus
用于让组件与App
通信。它们触发 App
可以处理的事件(登录类型事件)。我发现以 oncreate
方法显示的方式传递 Eventbus
很方便,我可以在每个组件的 oncreate
中使用 Eventbus
让组件触发事件。