[译]AngularJS应用程序中的TypeScript入门
By robot-v1.0
本文链接 https://www.kyfws.com/applications/getting-started-with-typescript-in-angularjs-appli-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 15 分钟阅读 - 7324 个词 阅读量 0[译]AngularJS应用程序中的TypeScript入门
原文地址:https://www.codeproject.com/Articles/888764/Getting-started-with-TypeScript-in-AngularJS-appli
原文作者:Nishant_Chaturvedi
译文由本站 robot-v1.0 翻译
前言
This article helps you get started with TypeScript in AngularJS application.
本文可帮助您开始使用AngularJS应用程序中的TypeScript.
介绍(Introduction)
AngularJS在所有前端Web开发框架中都是无可争议的拥护者,所以我不是专家可以说,因为老实说我没有与其他流行的库(例如Knockout,bone,anmberJS等)合作很多,但是最近几个月我一直在探索AngularJS,我很喜欢它.(AngularJS is an undisputed champion among all the front end web development frameworks, well I am no expert to say that since honestly I have not worked much with other popular libraries like Knockout, backbone, amberJS etc. but for last few months I have been exploring the AngularJS and I am loving it.)
AngularJS带来了很多好处,它的设计非常好,健壮且经过深思熟虑.我认为,如果您是网络开发人员,那么即使您在前端工作不多并且不打算在不久的将来在项目中使用它,花时间学习angularJS也完全值得.(AngularJS brings several goodies to the table, it’s very well designed, robust and well thought framework. In my opinion if you are a web developer, it’s totally worth it to invest your time learning angularJS even if you do not work much on the front end and do not plan to use it in your project in near future.)
背景(Background)
随着ng-conf中有关angularJS和TypeScript合作的公告以及" Angular 2:构建于打字稿上"的公告,开发人员社区似乎有很多动力从JavaScript过渡到angularJS项目的TypeScript.我既不是TypeScript的拥护者,也不是JavaScript的忠实拥护者,但是在本文中,我将向您展示如何使用Typescript入门angularJS,避免在TypeScript和JavaScript之间进行任何比较.(With the announcement in ng-conf about angularJS and TypeScript collaboration and “Angular 2: built on typescript” anouncement, there seems to be a lot of momentum shift in the developers community from JavaScript to TypeScript for angularJS projects. I am no advocate of TypeScript and also a big fan of JavaScript however in this article I’ll show you how to get started with angularJS using Typescript, avoiding any comparison between TypeScript and JavaScript.)
在本文结尾处我们要实现什么?(What are we going to achieve at the end of this article?)
我们将使用TypeScript构建一个非常简单的AngularJS应用程序.此应用程序将带有一个名为"获取收藏的曲目"按钮的视图.单击按钮将显示曲目列表,这很简单吗?(We are going to build a very simple AngularJS application using TypeScript. This application will have one view with a button named “Get favorite tracks”. On button click it will show a list of tracks, simple enough isn’t it?)
我将使用Visual Studio 2013创建演示应用程序,并且不会使用任何REST API来简化它.(I will use visual studio 2013 for creating the demo application, and won’t use any REST API to keep it short.)
注意:尽管附件解决方案是在VS 2013中创建的,但实际上并不需要,您可以下载附件代码并仅在解决方案内部复制代码(当然不包括.sln和.proj文件),并且它无需更改即可工作任何IDE.(Note: Although the attached solution is created in VS 2013, it’s really not needed, you can download the attached code and just copy the code inside solution (excluding the .sln and .proj files of course) and it should work without any modification with any IDE.)
聊够了,让我们开始吧.(Enough talk, let’s get started.)
建立项目结构(Creating project structure)
打开Visual Studio并创建并清空Web项目.删除web.config文件,我们不需要它.使用nuget软件包管理器添加以下参考,您甚至可以直接添加这些参考,nuget是可选的.(Open visual studio and create and empty web projecct. Delete the web.config file, we do not need it. Use nuget package manager to add following references, you can even add these directly, nuget is optional.)
- AngularJS.Core(AngularJS.Core)
- AngularJS.Route(AngularJS.Route)
- angularjs.TypeScript.DefinitelyTyped(用于AngularJS的TypeScript定义)(angularjs.TypeScript.DefinitelyTyped (this is for TypeScript definitions of AngularJS)) (可选)您可以添加引导程序来设置应用程序样式.(Optionally you can add bootstrap to style your app.)
在项目的根目录中创建一个名为" app"的文件夹,我们将在其中添加应用程序的代码.(Create a folder named “app” in the root of the project, this is where we will add our application’s code.)
创建界面(Creating Interfaces)
在我们的应用程序中,我们将使用AngularJS服务,该服务将与后端REST API通信以便获取轨道列表.我想将所有接口定义与主要业务逻辑分开,所以让我们在" app"中创建一个名为" interfaces"的文件夹,在该文件夹中创建一个空白的打字稿文件并在其中添加以下代码.(In our app, we are going to use an AngularJS service which will communicate with the backend REST API in order to fetch tracks list. I like to keep all the interfaces definitions separate from main business logic, so let’s create another folder inside “app” named “interfaces”, inside this folder create a blank typescript file and add following code in it.)
module angularWithTS.Interfaces {
export interface IPlaylistService {
getPlayList: () => Array<ITrack>;
}
export interface ITrack {
title: string;
artist: string;
rating: number;
}
}
在这里,我们创建了一个名为" angularWithTS.Interfaces"的打字稿模块,请注意,打字稿模块更像是其他编程语言中的名称空间,它与angularJS模块无关,但是稍后您将看到我将其命名为angular模块" angularWithTS"只是我个人的命名方式,但是您可以随意命名.(Here we have created a typescript module named “angularWithTS.Interfaces”, please note that typescript module is more like the namespace in other programming languages and it has nothing to do with the angularJS module, however you will see later that I have named angular module “angularWithTS” which is just my personal style of naming things but you can definitely name it whatever you like.)
您可以看到我在此文件中添加了两个接口定义.接口" IPlaylistService"有一个方法定义的名称为" getPlayList",方法签名表明它没有任何参数,并返回一个ITrack数组.(You can see I have added two interface definitions in this file. Interface “IPlaylistService” has one method defined name “getPlayList” and method signature tells that it does not take any parameter and returns an Array of ITrack.)
ITrack只不过是在同一文件中定义的另一个接口,该接口定义了我们的跟踪对象的协定,使用接口可确保在应用程序中不传递任何随机对象,并避免代码中出现意外错误.这是TypeScript最吸引人的功能之一.(ITrack is nothing but another interface defined in the same file which defines the contract of our track objects, using interfaces ensures that no random objects are passed around in our application and saves us from unexpected bugs in our code. This is one of the most shout features of TypeScript.)
实施接口(Implementing Interfaces)
因此,您已经定义了服务接口" IPlaylistService",现在让我们实现它.在" app"文件夹中创建另一个文件夹,并将其命名为" services",现在添加一个名为" playlistService.ts"的新打字稿文件,并在该文件中添加以下代码.(So you have defined the service interface “IPlaylistService” now let’s implement it. Create another folder inside “app” folder and name it “services”, Now add a new typescript file named “playlistService.ts” add the following code in this file.)
/// <reference path="../interfaces/interfaces.ts" />
module angularWithTS.Services {
export class PlayListService implements angularWithTS.Interfaces.IPlaylistService {
httpService: ng.IHttpService
static $inject = ["$http"];
constructor($http: ng.IHttpService) {
this.httpService = $http;
}
getPlayList = () => {
//For the purpose of this demo I am returning the hard coded values, hoever in real world application
//You would probably use "this.httpService.get" method to call backend REST apis to fetch the data from server.
var res: Array<angularWithTS.Interfaces.ITrack> = [
{ title: "Numb", artist: "Linkin Park", rating: 5 },
{ title: "Fire Flies", artist: "Owl City", rating: 4.3 },
{ title: "Yellow", artist: "coldplay", rating: 4.5 },
{ title: "Skyfall", artist: "Adele", rating: 4.5 }
];
return res;
}
}
angular.module("angularWithTS").service("angularWithTS.Services.PlayListService", PlayListService);
}
从上面的代码中可以看到,我们将服务封装在另一个名称空间" angularWithTS.Services"中.此外," export"关键字还可以确保可以从" angularWithTS.Services"模块调用我们的服务,而不仅仅是在模块本地.(as you can see in the above code, we are encapsulating our service inside another namespace “angularWithTS.Services”. Also “export” keyword ensures that our service will be available to be called from “angularWithTS.Services” module and is not just local to module.)
为了创建服务,我们创建一个新类,该类实现" IPlaylistService"接口.在AngularJS应用程序中有5种不同的创建服务的方式(服务,工厂,提供者,价值和常量),它们都有自己的用例和局限性. AngularJS称他们为(To create a service we create a new class which implements the “IPlaylistService” interface. There are 5 different ways to create services in an AngularJS application namely (service, factory, provider, value and constant), all with their own use cases and limitations. AngularJS calls them)**食谱(recipes)**创建服务,而配方名称之一就是我为此演示选择的服务.(to create services and one of the recipe name is service that’s I have chosen for the purpose of this demo.)
我知道创建服务的服务秘诀确实令人困惑,但是由于AngularJS团队并未就命名问题征询我们的意见,因此我们将尝试使用它.您可以在AngularJS开发人员指南中找到有关服务的更多信息.(I know service recipe to create service is really confusing but since AngularJS team did not consult us for naming things we will try to live with it. You can find more information about the services in AngularJS developer’s guide.)
我们的服务需要与后端API通讯,因此需要angularJS服务" $ http".我们可以在服务构造函数中指定此依赖关系,该依赖关系将在运行时满足.(Our service needs to talk to the backend APIs and hence needs angularJS service “$http”. We can specify this dependency in the service constructor which angular will fulfil at run time.)
请注意,函数的参数名为" $ http",其类型指定为" ng.IHttpService",但是,要通过受欢迎的前端工具(如Grunt和Gulp)的压缩和压缩过程使服务类成为服务类,您需要做一个添加步骤,如下所示.(Please note that function’s parameter is named “$http” and it’s type is specified as “ng.IHttpService”, however to make your service class servive through minification and compression process of popular front end tools like Grunt and Gulp, you need to do one addition step and shown below.)
static $inject = ["$http"];
$ inject是angularJS框架将要使用的特殊属性,请确保将其标记为"静态",其值是一个字符串数组,每个字符串都是特定服务的标识,以及在一个字符串中添加字符串的顺序数组很重要,此顺序应与构造函数参数顺序相同. AngularJS将在运行时检查此属性,以确定需要注入哪些服务.($inject is an special property which angularJS framework will consume, make sure it’s marked as “static”, it’s value is an array of strings, and each string is an identifies for a particular service, also the order in which strings are added in an array is important, this order should be the same as constructor parameters order. AngularJS will check this property at runtime to determine what are the services it needs to inject.)
您还可以看到我们的服务确实从" IPlaylistService"接口实现了" getPlayList"功能,但是我们实际上并没有调用任何REST api,而是返回了硬编码值,但是我相信您已经有了主意.(You can also see our service does implement the “getPlayList” function from the “IPlaylistService” interface, however we are not actually calling any REST apis rather returning the hard coded values, but I believe you got the Idea.) ()
angular.module("angularWithTS").service("angularWithTS.Services.PlayListService", PlayListService);
上一行是标准AngularJS代码,它将我们的类作为服务添加到angularJS模块中.我们尚未为我们的应用程序创建角度模块,因此让我们接下来创建一个.(previous line is standard AngularJS code which adds our class to angularJS module as a service. We are yet to create the angular module for our app so lets create one next.)
创建AngularJS模块(Creating the AngularJS module)
要创建模块,请在" app"文件夹中添加" app.module.ts"文件,我喜欢这样命名模块文件,但同样,这只是个人喜好.在" app.module.ts"文件中,添加以下代码:-(To create the module add “app.module.ts” file in “app” folder, I like to name module file like this but again it’s just personal preference. Inside “app.module.ts” file add the following code:-)
((): void=> {
var app = angular.module("angularWithTS", ['ngRoute']);
app.config(angularWithTS.Routes.configureRoutes);
})()
我们添加了IIFE,并使用了打字稿lambda函数来定义我们的代码.里面是所有标准的角度代码,在第一行中,我们创建一个名为" angularWithTS"的angularJS模块,该模块依赖于" ngRoute"模块,在下一行中,我们通过提供函数引用来为我们的应用配置路由信息在尚未创建的" angularWithTS.Routes"类中定义,因此让我们快速创建它.(we have added IIFE and used typescript lambda function to define our code. Inside that it’s all standard angular code, where in the first line we are creating an angularJS module named “angularWithTS” which has dependency on ‘ngRoute’ module, in the next line we are configuring our app with routing information by providing a function reference which is defined in “angularWithTS.Routes” class which we have not yet created so let’s quickly create that.)
定义路线(Defining the routes)
在" app"文件夹中添加另一个文件名" app.routes.ts",并在其中添加以下代码:-(Add another file name “app.routes.ts” in “app” folder, and add following code in it:-)
/// <reference path="../scripts/typings/angularjs/angular.d.ts" />
/// <reference path="../scripts/typings/angularjs/angular-route.d.ts" />
module angularWithTS {
export class Routes {
static $inject = ["$routeProvider"];
static configureRoutes($routeProvider: ng.route.IRouteProvider) {
$routeProvider.when("/home", { controller: "angularWithTS.controllers.tsDemoController", templateUrl: "/app/views/playlist.html", controllerAs: "playList" });
$routeProvider.otherwise({ redirectTo: "/home" });
}
}
}
上面的代码非常简单,但是我想强调一件事,即注册的第一条路线的" controllerAs"参数.为此" playList"提供的值表示,将通过此路由的视图内的" playList"别名访问绑定到该路由的控制器.(Code above is pretty straight forward however I would like to highlight one thing that is “controllerAs” parameter for the first route registered. Value provided for this “playList” says, controller bound to the route will be accessible with “playList” alias inside the view for this route.)
需要特别注意的是,因为您可以借助此别名访问控制器的属性/方法,而不必依赖于该控制器的" $ scope".我们已经将" angularWithTS.controllers.tsDemoController"控制器映射到了我们接下来要创建的路由.(This is important to note, since you can access controllers property/methods with the help of this alias rather relying on the “$scope” of that controller. We have mapped “angularWithTS.controllers.tsDemoController” controller to our route which we are going to create next.)
创建控制器(Creating the controller)
让我们通过在名为" controllers"的" app"文件夹中添加一个新文件夹并添加一个新的打字稿文件名为" tsDemoController.ts"并添加以下代码来创建控制器.(Let’s create the controller by adding a new folder inside “app” folder named “controllers” and add a new typescript file name “tsDemoController.ts” and add the following code.)
/// <reference path="../services/playlistservice.ts" />
/// <reference path="../interfaces/interfaces.ts" />
/// <reference path="../../scripts/typings/angularjs/angular.d.ts" />
module angularWithTS.controllers {
export class TSDemoController {
playListService: angularWithTS.Interfaces.IPlaylistService;
static $inject = ["angularWithTS.Services.PlayListService"];
constructor(playListService: angularWithTS.Interfaces.IPlaylistService) {
this.playListService = playListService;
}
favorites: Array<angularWithTS.Interfaces.ITrack>;
getFavourites = () => {
this.favorites = this.playListService.getPlayList();
}
}
angular.module("angularWithTS").controller("angularWithTS.controllers.tsDemoController", TSDemoController);
}
我们为输出控制器创建了一个名为" TSDemoController"的新类,并在构造函数中指定了它对" angularWithTS.Services.PlayListService"服务的依赖.再次注意" $ inject"属性.(We have created a new class for out controller named “TSDemoController” and have specified it’s dependency on “angularWithTS.Services.PlayListService” service in the constructor. Notice the “$inject” property again.)
我们的控制器具有一个名为" favorites"的属性,该属性的类型为" Array <angularWithTS.Interfaces.ITrack>",我们将使用此属性来绑定我们的视图.它还具有一个名为" getFavourites"的函数,该函数仅使用服务调用的结果填充" favorites"属性.我们将在我们的视图中将此函数用作单击事件处理程序.接下来,我们将创建视图.(Our controller has a property named “favorites” which has a type of “Array<angularWithTS.Interfaces.ITrack>” we will use this property to bind our view. It also has a function named “getFavourites” which simply populate the “favorites” property with the result of service call. We will use this function as a click event handler in our view. Next we will create the view.)
创建视图(Creating the view)
要将视图添加到我们的项目中,请在" app"文件夹中添加另一个名为" views"的文件夹,并添加一个空的html文件" playlist.html".在html文件中添加以下代码:(To add view to our project add another folder named “views” in “app” folder and add an empty html file “playlist.html”. Add the following code in the html file:)
<div class="jumbotron">
<ul class="list-group">
<li ng-show="playList.favorites" class="list-group-item" ng-repeat="t in playList.favorites">
{{t.title}}
</li>
</ul>
<button class="btn btn-block" ng-click="playList.getFavourites()">Get Favorites Tracks</button>
</div>
如您所见,我们通过诸如" playList.favorites"之类的别名访问控制器属性" favorites",而不依赖于" $ scope".其余的内容不言自明.(As you can see we are accessing controller property “favorites” via alias like “playList.favorites” and not relying on “$scope”. Rest of it is self-explanatory.)
汇集全部(Bringing it all together)
最后,我们几乎完成了该应用程序,让我们在应用程序''中添加一个shell
Index.html'‘文件,如下所示,确保您在项目中添加了所有第三方脚本和CSS文件,这些文件都在索引中引用了. html.(Finally we have almost completed the application, lets add a shell “Index.html” file in the “app” as shown below, make sure you have all the third party scripts and CSS files added in your project which are referenced in the Index.html.)
<!DOCTYPE html>
<html ng-app="angularWithTS">
<head>
<title>AngularJS With TypeScript</title>
<link href="content/css/bootstrap.min.css" rel="stylesheet" />
<link href="content/css/bootstrap.custom.min.css" rel="stylesheet" />
</head>
<body>
<div class="container">
<div class="page-header">Click the following button to get your favorite tracks.</div>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div ng-view="">
</div>
</div>
</div>
</div>
<script src="scripts/angular.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="app/app.routes.js"></script>
<script src="app/app.module.js"></script>
<script src="app/services/playlistService.js"></script>
<script src="app/controllers/tsDemoController.js"></script>
</body>
</html>
结论(Conclusion)
在本文中,我几乎没有涉及任何内容.当然,一篇文章不能对AngularJS或TypeScript都公平.希望它可以帮助您入门angularJS项目中的TypeScript.(I have barely scratched the surface in this article. Of course one article cannot do the justice to either of AngularJS or TypeScript. Hopefully it helps you to get started with TypeScript in angularJS project.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
Javascript HTML Typescript C# VS2013 AngularJs web_development client-side 新闻 翻译