AngularJS-处理手动输入URL状态的最佳方式
AngularJS - Best Way to Handle State on Manually Entered URLs
我目前有一个基于meanjs堆栈样板的设置,在这里我可以让用户在浏览网站URL时处于"登录"状态。这是由于将用户对象保存在全局可用的服务中。
然而,只有当我从我的基本根目录(即从"/"和仅在我的应用程序中导航)进行导航时,这才有效。
如果我手动输入诸如"/page1"之类的URL,它将丢失全局用户对象,但是,如果我转到根主页并通过网站导航到"/pages1"。然后就可以了,它在Service对象中看到全局用户对象。
所以我想这是由于整个页面刷新会丢失全局值,而通过网站导航时不会进行刷新,因此您保留了所有变量。
需要注意的一些事项:
- 我已启用HTML5Mode,使用前缀"!"
- 我使用UI路由器
- 我使用带有"/"的标记
- 我在express上有一个重写规则,在加载所有路由后,我有最后一个路由,它将所有"/*"都带到根index.html文件并发送回,因为angularjs的东西就在那里
我只是想知道这里的人们通常都做什么?他们是否恢复标准cookie和本地存储解决方案?我对angular还很陌生,所以我猜有一些库可以做这件事。
我只是想知道处理这件事的建议方法是什么,或者大多数人会怎么做,这样我就可以以正确的方式和有角度的方式保持一致。
更新:
如果我通过地址栏手动导航到我的网站上的另一个URL,我会丢失我的用户状态,但是如果我手动通过地址栏返回到我的根目录,我的用户状况会再次出现,所以这不仅仅是在窗口刷新时丢失状态。所以它似乎和根URL上运行的代码有关。
我有一个明确的重写,手动输入的URL(由于HTML5定位模式)应该首先返回index.html,因为它包含AngularJs文件,然后UI路由接管并正确路由它。
所以我本以为根上的任何代码都会执行,所以它应该类似于通过网站导航或在地址栏中键入。我一定错过了一些关于Angular的有这种效果的东西。
更新2
是的,所以更多的调查让我想到了这个:
<script type="text/javascript">
var user = {{ user | json | safe }};
</script>
这是index.html的服务器端代码,我想在通过手动URL将页面刷新到新页面时不会运行。
使用hash bang模式,它是有效的,这是因为使用hash bang模式,即使我在浏览器中键入URL,它也不会引起刷新,而使用HTML5模式时,它确实会刷新。所以现在我能想到的解决方案是使用sessionStorage。
除非有更好的选择?
更新3:
在使用HTML5Mode时,处理这一问题的最佳方法似乎是,您只需要在express服务器上重写一次,而不需要做其他事情。
我认为你说得对,但你可能想看看你的应用程序可能需要的所有路线,只考虑一些基本结构(api、用户、会话、部分等)。这似乎是一个问题,它就像你想让它变得多么复杂。
就最佳实践而言,您可以遵循角全堆栈生成器或meanio项目。
你所做的看起来最接近平均值。io主要是因为他们也使用ui路由器,尽管他们似乎保留了hashbang,而且它看起来更像是一个SEO友好型,具有一些独立的SPA页面功能。你可能可以安装它并在我在这里解释之前找到代码,所以-
npm install -g meanio
mean init name
cd [name] && npm install
有角度的全栈看起来像这样,这是一个更典型的路由的好例子:
// Server API Routes
app.route('/api/awesomeThings')
.get(api.awesomeThings);
app.route('/api/users')
.post(users.create)
.put(users.changePassword);
app.route('/api/users/me')
.get(users.me);
app.route('/api/users/:id')
.get(users.show);
app.route('/api/session')
.post(session.login)
.delete(session.logout);
// All undefined api routes should return a 404
app.route('/api/*')
.get(function(req, res) {
res.send(404);
});
// All other routes to use Angular routing in app/scripts/app.js
app.route('/partials/*')
.get(index.partials);
app.route('/*')
.get( middleware.setUserCookie, index.index);
然后,为了简单起见,使用一些正则表达式找到部分,并在不进行渲染的情况下交付,如:
var path = require('path');
exports.partials = function(req, res) {
var stripped = req.url.split('.')[0];
var requestedView = path.join('./', stripped);
res.render(requestedView, function(err, html) {
if(err) {
console.log("Error rendering partial '" + requestedView + "''n", err);
res.status(404);
res.send(404);
} else {
res.send(html);
}
});
};
并且索引被呈现:
exports.index = function(req, res) {
res.render('index');
};
最后,我确实遇到了一些麻烦,但通过做一些可以分解为步骤的事情,我成功地让它发挥了作用,这些步骤适用于那些使用HTML5Mode的人。
1)在Angular中启用HTML5Mode后,在服务器上设置重写,以便它发回包含Angular src-js文件的index.html。注意,这个re-write应该在静态文件和正常服务器路由之后(例如,在REST API路由之后)。
2)确保角度路由与服务器路由不同。因此,如果你有一个前端状态/user/帐户,那么就没有服务器路由/user/账户,否则它将不会被调用,请将你的服务器端路由更改为/api/v1/server/route。
3)对于前端中所有旨在触发对服务器的直接调用而不必经过角度状态/路由的锚标记,请确保添加"target=_self"。
- 在localhost Dev Box上测试JSONP请求的最佳方式
- 为react组件传递道具的最佳方式
- 让Webpack管理Quirky AMD定义的最佳方式
- 在承诺链中处理早期回报的最佳方式
- 在ng重复循环中显示条件内容的最佳方式是什么
- 在phonegap中为android调用onload函数的最佳方式
- 链接两个网页或网络应用程序的最佳方式
- 什么's是连接供应商js文件的最佳方式
- 什么's是在javascript中迭代项的最佳方式
- 在node.js中编写单元测试的最佳方式是什么
- 在页面上记录数据并实现pushstate()的最佳方式
- 使用AJAX在Rails中提交动态表单的最佳方式是什么
- 什么'这是加载jQuery的最佳方式
- 将大数组(字符串和类型数组的混合物)存储到blob或文件中/从blob或文件检索大数组的最佳方式
- 在网站上显示.mov作为加载屏幕的最佳方式
- 使用Angular存储用户以前是否选中过复选框,然后再调用它的最佳方式是什么
- 以角度渲染表中数据的最佳方式
- 删除集合中旧邮件/帖子的最佳方式
- 显示全屏Ajax加载程序的最佳方式
- PHP和JS中表单验证的最佳方式