angularjs单页应用_使用AngularJS将您的Web应用程序转换为单页

angularjs单页应用

介绍 (Introduction)

You have your nice classic multi-page web application and you want to move to the new Single-Page (SPA) framework. I am assuming here that you've chosen AngularJS 1.x or AngularJS 2.x as your SPA framework but, if not it's not a big deal. Pretty much everything will still apply as long as it's MV* oriented.

您拥有漂亮的经典多页Web应用程序,并且想要转到新的单页(SPA)框架。 我在这里假设您选择了AngularJS 1.xAngularJS 2.x作为SPA框架,但是,如果不是,那没什么大不了的。 只要面向MV *,几乎所有内容仍然适用。

Ideally, at this point, you should be asking yourself:

理想情况下,此时,您应该问自己:

  • What skills do I need to have in the team?

    我需要在团队中拥有什么技能?
  • What should I be aware?

    我应该注意些什么?
  • From where should I start?

    我应该从哪里开始?
  • What would be the best approach?

    最好的方法是什么?
  • How do I estimate the necessary time?

    如何估算必要的时间?

训练你的团队 (Train your team)

If I would have to choose the most important thing in order to succeed in this migration process I would say: 

如果我必须选择最重要的事情才能成功完成此迁移过程,我会说:

Train your team!!.

训练你的团队!

Really, I can’t stress this enough.

真的,我对此压力不足。

If your team is not completely aligned regarding knowledge and processes, this will fail, badly. The core knowledge needed is not only on AngularJS (or any other framework); you need to have a deep and solid understanding of JavaScript itself. Here’s my preferred list of resources I usually propose to my teams and trainees:

如果您的团队在知识和流程方面不完全一致,那将非常失败。 所需的核心知识不仅在AngularJS(或任何其他框架)上; 您需要对JavaScript本身有深刻而扎实的理解。 这是我通常向团队和受训人员推荐的资源清单:

图书 (Books)

制定策略 (Define a strategy)

In everything we do we should define a strategy, even if it’s a shallow one; something is always better than nothing.

在我们做的每一件事中,我们都应该定义一项策略,即使这是一项浅薄的策略; 总有总比没有好。

It's very important that you don’t start changing code all over the place otherwise you’ll end up with an uncontrolled number of regressions and frustration will kill you.

非常重要的一点是, 不要在所有地方开始更改代码,否则最终将导致数量不受控制的回归,而挫败感将使您丧命。

Do things incrementally逐步执行操作

It’s also very important that you don’t block the delivery of new features. You must keep delivering added value to your application alongside with your technical debt tasks. Of course, there’s always a bit of a compromise here, and you won’t be able to fit as many features in your sprint but don’t stop it completely.

不要阻塞新功能的交付也很重要。 您必须继续为应用程序提供附加值以及技术债务任务。 当然,这里总是会有一些折衷,并且您将无法在sprint中容纳尽可能多的功能,但不能完全停止它。

Here’s the approach I like to follow:

这是我喜欢遵循的方法:

阶段1:拆分控制器 (Phase 1: Split the controllers)

One good way is to keep the single-page paradigm aside at first and migrate the views, one by one to Angular. Doing it like this, the pages will keep being delivered by as usual from server-side but all the dynamic elements will be rendered with Angular. The site will keep on working and some views will be Angular others are legacy code and changing views will still trigger a full page refresh.

一种好方法是首先保留单页范例,然后将视图一个一个地迁移到Angular。 这样,页面将继续照常从服务器端传递,但是所有动态元素都将使用Angular呈现。 该站点将继续工作,某些视图将变为Angular,而其他视图则为旧代码,更改视图仍将触发整个页面的刷新。

()

MVC in the back-end?

在后端的MVC?

During this process, you’ll be “forced” to clean-up your server-side controllers and make new ones that return JSON instead of HTML. These will be the AJAX endpoints of your Angular service that will handle all the $http requests. You’ll end up with one controller method to deliver the HTML view and a bunch of other methods that implement the necessary CRUD. I advise to prefix all the CRUD routes with /api/ as this will help you isolate the routes that return JSON from the ones that return HTML.

在此过程中,您将被“强制”清理服务器端控制器,并使新控制器返回JSON而不是HTML。 这些将是Angular服务的AJAX端点,它将处理所有$ http请求。 最后,您将获得一个提供HTML视图的控制器方法,以及一系列实现必要CRUD的其他方法。 我建议给所有CRUD路由加上/ api /前缀,因为这将帮助您将返回JSON的路由与返回HTML的路由隔离开。

No pressure, take your time. Meanwhile, new screens and improvements that you have in the pipeline should be done directly in Angular.

没有压力,慢慢来。 同时,应该在Angular中直接完成管道中的新屏幕和改进。

()

No MVC in the back-end?

后端没有MVC?

If you’re not using MVC on the back-end, the process should be more or less the same as described above anyway with the exception that you might want to use another technology to handle your AJAX requests. Here are some options depending on your server-side technology:

如果您不在后端使用MVC,则该过程无论如何都应与上述大致相同,但您可能希望使用另一种技术来处理AJAX请求。 以下是一些选项,具体取决于您的服务器端技术:

The list goes on, and each platform has multiple options; choose your own!

清单继续进行,每个平台都有多个选项。 选择你自己的!

阶段2:开始使用Angular管理状态 (Phase 2: Start managing state with Angular)

This part will take you some time to figure out and debug.

这部分将花费您一些时间来找出并调试。

Basically, you’ll need to move all the user states to Angular, more specifically into a separate Angular service/factory that will be used by all Angular controllers. It’s this mechanism that will allow you later to hit F5 in the browser and still get the needed logged in user information and permissions. You achieve this by adding a controller on the server that you can do an AJAX call and retrieve this information.

基本上,您需要将所有用户状态移动到Angular,更具体地说,将其移动到将由所有Angular控制器使用的单独的Angular服务/工厂中。 通过这种机制,您以后可以在浏览器中按F5键,并且仍然获得所需的登录用户信息和权限。 您可以通过在服务器上添加一个控制器来实现此目的,该控制器可以进行AJAX调用并检索此信息。

()

Phase 3: Add ng-route

阶段3:添加ng-route

Once all the views are converted and are able to manage their states, it’s time to add ng-route to the mix. It’s not mandatory, but this should ideally be a one-shot mission for all views. If all the above is completed, it won’t take you that long.

一旦所有的视图都被转换并且能够管理它们的状态,就该添加ng-route了。 这不是强制性的,但是理想情况下,这应该是所有视图的一次性操作。 如果以上所有步骤均已完成,那么您就不会花那么长时间。

What you need to do here is to drop all the controller methods that render HTML leaving only one that delivers the main page. Move all your views routing logic to Angular leaving only the API routes on the back-end (if you prefix them like I said above, they will be easy to identify).

您需要在此处删除所有呈现HTML的控制器方法,只剩下一个传递主页的方法。 将您所有的视图路由逻辑移至Angular,仅在后端保留API路由(如果像我上面所说的那样给它们添加前缀,它们将很容易识别)。

()

Phase 4: The login page

阶段4:登录页面

In all this, I never mentioned the login page; that was on purpose.

在这一切中,我从未提及登录页面; 那是故意的。

I leave this part to the end because having to do a full page refresh every time you login/logout will be useful to clean up some nasty global and badly written JavaScript you might have.

我将这部分放在最后,因为每次登录/注销时都必须刷​​新整个页面,这对于清理您可能拥有的一些讨厌的全局且编写错误JavaScript很有用。

Moving the login page into the single-page framework means that you don’t do a form post to login, you do it by an  AJAX request and you need to populate your previously prepared state service (Phase 2). You also have to clean this informantion once you logout or you will get a 401 from the server and redirect to the login view. 

将登录页面移至单页框架意味着您无需进行表单登录即可登录,而是通过AJAX请求进行登录,并且需要填充先前准备的状态服务(第2阶段)。 注销后,您还必须清除此信息,否则将从服务器获取401并重定向到登录视图。

陷阱清单 (The pitfalls list)

During the process described above, you’ll face a lot of challenges and each time I had to do this exercise I kept a list of the problems I encountered and how I solved them. Below you’ll find this list.

在上述过程中,您将面临很多挑战,每次我必须进行此练习时,我都会列出所遇到的问题以及如何解决这些问题。 您将在下面找到此列表。

PF1:将页面JavaScript文件转换为控制器 (PF1: Converting the page JavaScript file into a controller)

Of course, you’re already using JavaScript in your site, so what should you do with it?

当然,您已经在网站中使用JavaScript,那么您应该如何使用它呢?

If you already use RequireJS or any other AMD mechanism then it’s easy because you already have your dependencies and encapsulation figured out. Each RequireJS module represents either a Controller or a Factory or Service in the Angular world so all you need is to slightly change the way you declare it.

如果您已经使用RequireJS或任何其他AMD机制,那么这很容易,因为您已经弄清了依赖项和封装。 每个RequireJS模块都代表Angular世界中的ControllerFactory或Service ,因此您所要做的只是稍微更改声明它的方式。

On the other hand, if you didn’t pay the appropriate attention to the way you handle your JavaScript then this will be a harder task. The time you’ll spend migrating each page into an AngularJS view will greatly depend on how well structured your current JavaScript is. 

另一方面,如果您没有适当地注意处理JavaScript的方式,那么这将是一项艰巨的任务。 将每个页面迁移到AngularJS视图所花费的时间将很大程度上取决于当前JavaScript的结构。

PF2:将代码拆分为工厂 (PF2: Splitting code into factories)

All reusable code should, or better, must be moved into a Factory or Directive. Good examples of this are states or data-related methods or code for popups that are used in multiple views. 

所有可重用的代码应或更佳地移入Factory或Directive。 一个很好的例子是在多个视图中使用的状态或与数据相关的方法或用于弹出窗口的代码。

PF3:考虑将功能分成几个模块是个好主意 (PF3: Think when it’s a good idea to split functionalities into several modules)

Modules in AngularJS are a great way to encapsulate logic or even to abstract enterprise level logic that can later on be reused in other applications. This way you can easily decouple dependencies and reuse the code later on. Thinking this ahead is a good idea; it won’t slow you down and will save you big refactorings later. 

AngularJS中的模块是封装逻辑甚至抽象企业级逻辑的好方法,这些逻辑以后可以在其他应用程序中重用。 这样,您可以轻松地分离依赖关系并在以后重用代码。 提前考虑这是一个好主意; 它不会减慢您的速度,并在以后节省大量的重构工作。

PF4:请注意库版本冲突 (PF4: Be aware of library version conflicts)

I recall this problem related to jQueryUI based FileUpload widget. We were using this JQueryUI widget that needed a jQueryUI version higher than the rest of our controls.

我记得这个与基于jQueryUI的FileUpload小部件有关的问题。 我们使用的JQueryUI小部件需要一个比其余控件更高的jQueryUI版本。

I agree this is a bad thing to have as it is, but this was a legacy site and the client had implemented this upload functionality on a separate page and didn’t want to update the other pages. All of the sudden, we were overriding one version of JQueryUI with another and breaking the whole site.

我同意这是一件坏事,但这是一个旧站点,并且客户端已在单独的页面上实现了此上传功能,并且不想更新其他页面。 突然之间,我们用一个版本的JQueryUI覆盖了另一个版本,并破坏了整个站点。

Another similar problem I also had with another site was with JQuery itself. Different versions of JQuery were being loaded by different components. In the Multi-Page world, this is a bad practice but hardly a breaking problem, but as we moved to single-page we had a conflict because the main page itself never changes. Be aware of this and enforce one single version for your components across the whole application. 

我在另一个站点上遇到的另一个类似问题是JQuery本身。 不同组件正在加载不同版本的JQuery。 在“多页”世界中,这是一个不好的做法,但几乎不是一个棘手的问题,但是当我们移至单页时,由于主页面本身永不更改,因此发生了冲突。 请注意这一点,并在整个应用程序中为您的组件实施一个单一版本。

PF5:绑定到文档的jQuery事件 (PF5: jQuery events bound to the document)

This is a JQuery best-practice that will make you lose some time. The problem is that, in a multi-page web application, each time you change page, you start on a clean plate. In a single-page scenario, the document is always the same, events bound to it will remain there even when the view changes. If we come to a view the event binds are set, let's say for a click of a button, moving to another page and coming back will make the events to be bound again resulting in multiple event handlers for the same event.

这是一种JQuery最佳实践,它将使您浪费一些时间。 问题在于,在多页Web应用程序中,每次更改页面时,您都必须从头开始。 在单页方案中,文档始终是相同的,即使视图发生更改,绑定到文档的事件也将保留在那里。 如果我们看到设置了事件绑定的视图,那么只需单击一下按钮,再移到另一页然后再返回,将使事件再次被绑定,从而导致同一事件的多个事件处理程序。

Example:

例:

$(document).on('click', '#btnNext', function(){ ... });

Solution:

解:

Use ng-click and handle your code in the controller. This is the correct way to do it and should always be the preferred solution.

使用ng键单击并在控制器中处理代码。 这是正确的方法,应该始终是首选解决方案。

Now there might be cases where you want to just postpone conversion to ng-click so here are some temporary solutions:

现在,在某些情况下,您可能只想推迟到ng-click的转换,因此这里有一些临时解决方案:

Temporary Solution 1

临时解决方案1

If the event handler can actually be bound directly to the element… do it.

如果事件处理程序实际上可以直接绑定到元素,请执行此操作。

Temporary Solution 2

临时解决方案2

If we need to make a delegate event handler, wrap each view with a div. Move the event handlers from the document to this wrapper div.

如果需要创建委托事件处理程序,请用div包装每个视图。 将事件处理程序从文档移到该包装div。

Temporary Solution 3

临时解决方案3

Sometimes, the same view/controller can be used in more than one parent view. A good example of this is popups and the correct solution is to wrap them in Directives but, if for some edge reason at the moment you can’t...

有时,同一视图/控制器可以在多个父视图中使用。 弹出式窗口就是一个很好的例子,正确的解决方案是将它们包装在Directives中,但是,如果由于某种原因,您现在还不能...

In this case we can’t use the main view wrapper div because it’s not always the same, so for these edge cases we remove the handler before adding it again:

在这种情况下,我们不能使用主视图包装div,因为它并不总是相同的,因此对于这些极端情况,我们在再次添加之前删除了处理程序:

var gotoNextPage = function(){ /* do your stuff */ };
$(document).off('click', '#btnNext', gotoNextPage);
$(document).on('click', '#btnNext', gotoNextPage);
Avoid this and any of the above temporary solutions if you can.如果可以,请避免使用此方法以及上述任何临时解决方案。

PF6:基于jQuery的控件/小部件将使……痛苦不已 (PF6: jQuery based controls/widgets will be a pain in the… neck)

Some of the jQuery widgets will fail to work properly, especially due to event-related problems. The ones that work won't comply to the Angular way of doing things.

某些jQuery小部件将无法正常工作,尤其是由于与事件相关的问题。 工作的人将不会遵循Angular的工作方式。

Reserve substantial time for this if you use a lot of these things (honor mentions to DatePicker, Dialog, jqGrid). A lot of alternatives already exist for most of them and you’ll see that wrapping them yourself with a Directive is usually not a bad alternative.

如果您使用很多其他东西(请在DatePicker,Dialog,jqGrid中提及),请为此预留大量时间。 其中大多数已经存在许多替代方案,您会发现用指令将它们自己包装起来通常不是一个不好的替代方案。

So, before starting the migration process, identify all your controls that might need to be worked out. If you work on them before starting a page migration, you’ll feel much more confident estimating the effort. 

因此,在开始迁移过程之前,确定所有可能需要制定的控件。 如果您在开始页面迁移之前就对它们进行了处理,那么估计工作量将更加自信。

PF7:登录页面仍然是单独的页面吗? (PF7: The Login page is still a separate page?)

This will require a lot of refactoring, rewriting and rethinking. Here’s a small list of pain points:

这将需要大量的重构,重写和重新思考。 以下是一些痛点:

  • Hiding the menus and everything else while you’re in the login page

    在登录页面时隐藏菜单和其他所有内容
  • Correctly redirecting/refreshing the view when you login/logout

    登录/注销时正确重定向/刷新视图
  • Handling the session information when you login/logout and press F5
    • Rethink everything related to the session data that was being handled server-side like user information, authorization, contextual data, etc…

    登录/注销并按F5时处理会话信息
    • 重新考虑与服务器端处理的会话数据相关的所有内容,例如用户信息,授权,上下文数据等…
  • Security, Some views will need to be requested from the server without security validation
    • The main change in the framework will be that you really need to stop concerning about hiding pages from the user. Your main concern is to secure data, not the HTML, and data is still coming and going to the server. Secure it there!

    安全性,需要从服务器请求某些视图而不进行安全性验证
    • 框架的主要变化是您真的需要停止对用户隐藏页面的关注。 您主要关心的是保护数据(而不是HTML)的安全,并且数据仍在服务器中来回移动。 固定在那里!
  • Make sure that all the states are rebuilt client-side if the user presses F5.
    • This often requires a separate AJAX call to get the user extra information based on the cookie that you already have.

    如果用户按F5,请确保所有状态都在客户端重建。
    • 这通常需要一个单独的AJAX调用,以根据您已经拥有的cookie为用户获取更多信息。
  • Move code into a security factory
    • Make sure all this code is “grouped” in a single reusable factory that is shared across all views.

    将代码移至安全工厂
    • 确保所有这些代码都被“分组”在一个可重用的工厂中,并在所有视图之间共享。

PF8:慢慢开始摆脱所有jQuery选择器 (PF8: Slowly start to get rid of all jQuery selectors)

This is kind of the end of the line for me. When you have the view fully working but jQuery is still being used inside your Angular Controllers. Take the extra time to get rid of them. The ultimate goal is to have zero jQuery selectors inside your Controllers. Choose to either replace them with native Directives and Services or create your own.

对我来说,这已经是终点。 当视图完全正常运行但jQuery仍在Angular Controllers中使用时。 花额外的时间摆脱它们。 最终目标是在Controller内拥有零个jQuery选择器。 选择用本地指令和服务替换它们,或者创建自己的指令和服务。

Things like 

$.ajax({})
$('#mybutton').on('click', function(){});
$http and  $ httpngClick respectively  ngClick分别

最后的笔记 (Final notes)

I’m not addressing any migration considerations here specific to Angular 2.0 but, apart from syntax changes, the overall considerations remain the same.

在这里,我没有讨论任何针对Angular 2.0的迁移注意事项,但除了语法更改外,总体注意事项保持不变。

This article was based on my personal experience and I’m sure many other challenges are missing here. If you happen to have something to add, please drop me a line and I’ll be happy to discuss it with you and perhaps, enrich this article.

本文是根据我的个人经验得出的,并且我确信这里还缺少许多其他挑战。 如果您碰巧要添加一些内容,请给我下一行,我很乐意与您讨论,也许可以丰富本文。

翻译自: https://www.experts-exchange.com/articles/22859/Converting-your-web-app-to-Single-Page-with-AngularJS.html

angularjs单页应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值