本文共 17367 字,大约阅读时间需要 57 分钟。
aurelia
is yet another component based JavaScript framework (not just library). It is an interesting one because of its simplicity and the use of futuristic tools like ES2016. This is a getting started guide for Aurelia and by the end you will know the basics of Aurelia and why it's worth a shot.
是另一个基于组件JavaScript框架(不仅仅是库)。 它之所以有趣是因为它的简单性以及对ES2016等未来派工具的使用。 这是Aurelia的入门指南,到最后,您将了解Aurelia的基础知识以及为什么值得一试。
Yeah! I get it. If you are like me, you must have started with Angular 1 which we all loved. React was introduced and because it is component based, therefore, the future, you had to learn it. Half way into your React journey, Angular 2 was released and you can't afford to miss it because every JS developer loves angular including you. Now you have 2 heavy tools to be asking questions about on Stack Overflow which we all know how that hurdle is difficult. And here I am telling you about another one.... what's the name again, yeah Aurelia
. I understand how you feel and I felt same way as well but after going through the cool stuffs Aurelia is bringing to the table, I couldn't help but give it a shot. Some of this cool benefits include:
是的 我知道了。 如果您像我一样,那么您必须从我们都喜欢的Angular 1开始。 引入了React,由于它是基于组件的,因此,未来,您必须学习它。 在您的React旅程进行到一半时,Angular 2已发布,您不能错过它,因为每个JS开发人员都喜欢包括您在内的angular。 现在,您有2个沉重的工具要问有关Stack Overflow的问题,我们都知道困难重重。 在这里,我要告诉您另一个。。。再说一次,是的, Aurelia
。 我了解您的感觉,也有相同的感觉,但是在浏览了Aurelia带来的精彩内容之后,我禁不住尝试一下。 这些很酷的好处包括:
Let's hop in and see for ourselves.
让我们跳进去看看。
We will make a mini Instagram app but before we build our killer IG photo app, it will be cool to have a quick look at Aurelia by creating a simple component first. You need to download the Aurelia , unzip the folder to your working directory, and rename the folder to scotch-aurelia
or what suites you.
我们将制作一个微型Instagram应用程序,但在构建我们的杀手级IG摄影应用程序之前,先创建一个简单的组件快速了解Aurelia是很酷的。 您需要下载Aurelia ,将该文件夹解压缩到您的工作目录中,然后将该文件夹重命名为scotch-aurelia
或您所需要的套件。
Install a dependent HTTP server to assist in running your app:
安装依赖于 HTTP服务器以帮助运行您的应用程序:
npm install -g http-server
Run:
跑:
http-server -o -c-1
The browser will show up with a welcome message as seen below. That is dumb enough for a first run.
浏览器将显示欢迎消息,如下所示。 对于第一次运行来说,这已经足够愚蠢了。
We can do better, let's explore the Aurelia world. Bearing in mind that this is a starter guide, we could skip some details and focus on primary subjects.
我们可以做得更好,让我们探索Aurelia世界。 请记住,这是入门指南,我们可以跳过一些细节,而专注于主要主题。
The index.html
on the root is used to bootstrap the app by:
根目录上的index.html
用于通过以下方式引导应用程序:
1) Using SystemJS to import aurelia-bootstrapper
2) Adding aurelia-app
to the markup body
1)使用SystemJS导入aurelia aurelia-bootstrapper
2)将aurelia-app
添加到标记body
Aurelia
Pretty straight forward, right? SystemJS and it's config was also imported before the bootstrap took place which makes sense.
很简单吧? 在引导发生之前,还导入了SystemJS及其配置,这很有意义。
Components in Aurelia by default are made up of a view (HTML template) and a view-model (JS class). Your project if otherwise configured will use app.js
and app.html
located in src
folder as entry component to your app. The starter project includes that so let's update them to see how data binding works:
默认情况下,Aurelia中的组件由一个视图(HTML模板)和一个视图模型(JS类)组成。 您的项目(如果进行了其他配置)将使用src
文件夹中的app.js
和app.html
作为应用程序的输入组件。 入门项目包括其中,因此让我们对其进行更新以查看数据绑定的工作方式:
// src/app.jsexport class App { // Properties message = 'Welcome to Aurelia!'; firstNum = 0; secondNum = 0; // Get method that returns the sum of the two integer properties get sum () { return parseInt(this.firstNum) + parseInt(this.secondNum); } submit () { alert(`Sum of ${ this.firstNum} and ${ this.secondNum} is ${ this.sum}`) }}
Three properties, two methods, no much surprise if you have basic programming skills. The amazing thing here is that the properties are what we can bind to our view and we can call the methods by triggering events:
具有三种属性,两种方法,如果您具有基本的编程技能,也就不足为奇了。 这里令人惊奇的是,属性是我们可以绑定到视图的内容,并且我们可以通过触发事件来调用方法:
${message}
The template is wrapped with template
thereby playing by the rules as suggested by W3C. Binding is made with .bind
and events with .trigger
. There are lots of options available in the Aurelia documentation but this is basically what we do in modern apps.
模板包装有template
从而按照W3C建议的规则进行播放。 用.bind
绑定,用.trigger
事件。 Aurelia文档中有很多可用的选项,但这基本上是我们在现代应用程序中所做的。
Time to build something fun and explore the awesomeness of Aurelia.
是时候建立一些有趣的事物并探索Aurelia的超凡魅力了。
To better explore Aurelia, let us build a simple Instagram app together. This will give us the chance to have a look at features like routing, HTTP requests, advanced templating, etc. To prepare for that, clear the contents of app.js
and app.html
.
为了更好地探索Aurelia,让我们一起构建一个简单的Instagram应用程序。 这将使我们有机会了解路由,HTTP请求,高级模板等功能。为此,请清除app.js
和app.html
的内容。
The existing app.js
which I earlier mentioned is the default app's entry component makes more sense to handle route logics:
我先前提到的现有app.js
是默认应用程序的入口组件,它对于处理路由逻辑更有意义:
// src/app.jsexport class App { // Implement configureRouter method configureRouter(config, router) { config.title = 'Scotch IG'; // Use map to set array of possible routes config.map([ { route: ['','home'], name: 'home', moduleId: './home', nav: true, title:'Home' }, { route: 'me', name: 'me', moduleId: './me', nav: true, title:'Me' } ]); // Create a binding to the router object this.router = router; }}
Simple as that. All you just need to configure routes in Aurelia is to Implement the configureRouter
method which takes two parameters - config
which is used to configure routes and router
which is an object of information about the routes. We also need to tell the framework where to mount other components when using routes. This is done in app.html
:
就那么简单。 您只需在Aurelia中配置路由就可以实现configureRouter
方法,该方法具有两个参数config
(用于配置路由)和router
是有关路由信息的对象)。 我们还需要告诉框架使用路由时在何处挂载其他组件。 这是在app.html
完成的:
The most significant content is the mount point specified with router-view
. That is where the components of each routes are loaded into when they are called upon. The weirdest thing (but actually amazing) here is that we are doing a require inside the template. Did we just load Bootstrap and FA? Yeah we did. Aurelia uses a module management system that will blow your mind. You can require anything (npm or Github) anywhere (markup or class). This is achieved by a package manager called JSPM
.
最重要的内容是由router-view
指定的安装点。 这是每个路由的组件在被调用时加载到的位置。 这里最奇怪的事情(但实际上很神奇)是我们正在模板中进行需求。 我们是否刚刚加载了Bootstrap和FA? 是的,我们做到了。 Aurelia使用的模块管理系统会让您大吃一惊。 您可以在任何地方(标记或类)要求任何内容(npm或Github)。 这是通过一个名为JSPM
的包管理器来实现的。
is a frictionless browser package management tool for for the , built on top of the dynamic .
是用于器的无摩擦浏览器软件包管理工具,基于动态构建。
You may have as well noticed that repeat
is used to loop through available navigation and bind to the view while if
expression is used to decisively show a spinner when changing routes. As you can see, Aurelia solves common daily routing issues seen in modern JS frameworks.
您可能已经注意到, repeat
用于在可用导航中循环并绑定到视图,而if
在更改路线时使用expression来决定性地显示微调器, if
可能会repeat
使用repeat
。 如您所见,Aurelia解决了现代JS框架中常见的日常路由问题。
We just created two routes whose components are missing, let us flesh those out:
我们只创建了两条路线,这些路线的组件缺失了,让我们充实它们:
// src/home.jsexport class Home { heading = "Welcome to Scotch IG";}
${heading}
// src/me.jsexport class Me { heading = "Me";}
${heading}
Now reload the browser and feel the awesomeness of Aurelia routing. Don't forget to notice the cool spinner, though it will be more useful in the next section where we explore HTTP. I know you have been waiting for that.
现在,重新加载浏览器并感受到Aurelia路由的强大功能。 不要忘记注意这个很棒的微调器,尽管它在下一部分探讨HTTP的过程中将更加有用。 我知道你一直在等待。
I don't know about you, but routing is not my favorite part in modern frameworks, Ajax is. Time to use Aurelia's futuristic fetch
which is also backward compatible to talk to Instagram's API.
我不了解您,但是路由并不是Ajax在现代框架中最喜欢的部分。 是时候使用Aurelia的未来派fetch
,该fetch
功能还可以向后兼容以与Instagram的API通讯。
Instagram API can be accessed only if an access_token
is provided by the requesting user. Basically, you get the user to sign in, Instagram assigns a token, then you grab that token and use it to make request on behalf of the user. Sounds like work? to the rescue. You can decide to go hardcore but these days everybody loves the word "frictionless".
只有请求用户提供access_token
才能访问Instagram API。 基本上,您使用户登录,Instagram分配了一个令牌,然后您抓取该令牌并使用它代表用户发出请求。 听起来像工作吗? 进行救援。 您可以决定成为铁杆,但如今,每个人都喜欢“无摩擦”这个词。
a new application on Instagram and store the CLIETN ID
and CLIENT SECRET
somewhere safe.
在Instagram上一个新应用程序,并将CLIETN ID
和CLIENT SECRET
存储在安全的地方。
Setup an , create an app from the dashboard (I named mine Scotch IG
)
设置 ,从信息中心创建一个应用(我叫mine Scotch IG
)
Enable Instagram from the dashboard by clicking connections, social and turning on Instagram. The hopefully stored Instagram credentials will be requested. Check the permission boxes and hit Save.
通过单击连接,社交并打开Instagram,从仪表板启用Instagram 。 希望存储的Instagram凭据将被请求。 选中权限框,然后单击“保存”。
The Apps
tab will be activated, turn on the App you created, in my case Scotch IG
.
“ Apps
标签将被激活,打开您创建的应用程序(在我的情况下为Scotch IG
。
Finally, go to the application settings and supply http://localhost:8080/#/
to the Allowed Callback URLs
then copy the Auth0 App Client ID. Save your settings. Trust me you have authentication setup with Instagram already.
最后,转到应用程序设置,并为Allowed Callback URLs
提供http://localhost:8080/#/
,然后复制Auth0 App Client ID。 保存设置。 相信我,您已经使用Instagram建立了身份验证设置。
In order not to loose track, let us complete the rest of this section in a stepwise manner:
为了不松懈,让我们逐步完成本节的其余部分:
Install JSPM globally and Auth0.js locally with JSPM
使用JSPM全局安装JSPM并在本地安装Auth0.js
# Install jspm globallynpm install -g jspm# Install auth0-js with jspmjspm install npm:auth0-js
A simple service to initialize Auth0 and sign user into Instagram:
一个用于初始化Auth0并将用户登录到Instagram的简单服务:
// src/auth-service.js// Import Auth0import Auth0 from 'auth0-js';export class AuthService { constructor() { // Initialize Auth0 this.auth0 = new Auth0({ domain: 'YOUR AUTH0 DOMAIN', clientID: 'YOUR AUTH0 CLIENT ID', callbackURL: 'http://localhost:8080/#/', callbackOnLocationHash: true }); } sigin() { //Keep a copy of 'original' this const _this = this; // Login with IG this.auth0.login({ connection: 'instagram', popup: true }, function(err, profile) { if (err) { alert("something went wrong: " + err.message); return; } // Use ID token to get Instagram user profile _this.auth0.getProfile(profile.idToken, function (err, profile) { if(err) { alert(err); return; } localStorage.setItem('token', profile.identities[0].access_token); }); }); } signout() { localStorage.removeItem('token'); }}
Auth0 will give you Auth0 credentials after a successful login but we can't query IG with that. That is why we request for the IG profile with auth.getProfile()
even after a login.
成功登录后,Auth0将为您提供Auth0凭据,但我们无法以此来查询IG。 这就是为什么即使在登录后我们也使用auth.getProfile()
请求IG配置文件的auth.getProfile()
。
It is important to note that we are storing in the token in localStorage
to enable us access it from any part of our SPA even after a reload.
重要的是要注意,我们将令牌存储在localStorage
,即使重新加载后也可以从SPA的任何部分访问令牌。
With the service written, we can inject it in our existing home.js
and use it to authenticate a user. Note that your app is in Sandbox mode which has a lot of limitation but has enough features for this tutorial.
编写服务后,我们可以将其注入到现有的home.js
并使用它来验证用户身份。 请注意,您的应用程序处于沙盒模式,该模式有很多限制,但具有本教程所需的足够功能。
// src/home.jsimport { inject} from 'aurelia-framework';import { AuthService} from './auth-service';// DI for AuthService@inject(AuthService)export class Home { heading = "Welcome to Scotch IG"; constructor(authService){ this.authService = authService; } sigin() { // Sign in this.authService.sigin(); } signout() { // Sign out this.authService.signout(); }}
All that is needed to leverage Aurelia's DI feature is to decorate the class with @inject
passing the injecatables
利用Aurelia的DI功能所需要做的就是用@inject
传递@inject
传递的东西来装饰类。
Then create a login button in the template:
然后在模板中创建一个登录按钮:
${heading}
3) Create Instagram Service First instal Aurelia's HTTP client for making JSONP request to IG:
3)创建Instagram服务首先安装Aurelia的HTTP客户端,以向IG发出JSONP请求:
jspminstall aurelia-http-client
The create an ig-service
file for our service class:
为我们的服务类创建一个ig-service
文件:
// src/ig-service.jsimport { inject} from 'aurelia-framework';import { HttpClient} from 'aurelia-http-client';//DI@inject(HttpClient)export class IgService { token = localStorage.getItem('token'); constructor(http) { //Configure basw URL http.configure(config => { config .withBaseUrl('https://api.instagram.com/v1/'); }); // Set http property this.http = http; } recent() { // Return a promise which when resolved will respond with recent posts return this.http.jsonp(`users/self/media/recent/?access_token=${ this.token}`, 'callback'); } me() { // Return a promise which when resolved will respond with user's profile return this.http.jsonp(`users/self/?access_token=${ this.token}`, 'callback'); }}
Let's consume our service in the home
and me
view models:
让我们消耗我们的服务在home
和me
查看模型:
// src/home.jsimport { inject} from 'aurelia-framework';import { AuthService} from './auth-service';import { IgService} from './ig-service';// Browser-based implementation of Aurelia's platform abstraction layer.// activate() will throw an error if missingimport { initialize} from 'aurelia-pal-browser';initialize()// DI for AuthService@inject(AuthService, IgService)export class Home { heading = "Welcome to Scotch IG"; constructor(authService, igService){ // Setup Dependencies this.authService = authService; this.igService = igService; } sigin() { // Sign in this.authService.sigin(); } signout() { // Sign out this.authService.signout(); } // Lifecycle method called when a route is activated activate() { if(localStorage.getItem('token')){ // Resolve promise returned from igService return this.igService.recent() .then(res => res.response.data) .then(recent => { // Bind to view this.recent = recent }); } }}
// src/me.jsimport { inject} from 'aurelia-framework';import { initialize} from 'aurelia-pal-browser';import { IgService} from './ig-service';initialize();// DI@inject(IgService)export class Me { heading = "Me"; me = { }; constructor(igService){ // initialize this.igService = igService; } activate() { if(localStorage.getItem('token')){ // Resolve promise return this.igService.me() .then(res => res.response.data) .then(me => { // Bind to view this.me = me }); } }}
Now we can use the basic binding techniques we have seen to flesh out our views:
现在,我们可以使用已经看到的基本绑定技术来充实我们的观点:
${heading}
Followed by: ${me.counts.followed_by}; Following: ${me.counts.follows}; Media: ${me.counts.media};
Your app would look like the following if you followed the steps right:
如果您按照正确的步骤操作,则您的应用程序将如下所示:
We have a fair introduction to Aurelia. Do not hesitate to visit the documentation as there are more fun stuff to explore. Maybe you might just end up using this framework in your next project or maybe introduce to a friend.
我们对Aurelia有一个公平的介绍。 请继续浏览文档,因为有更多有趣的东西可供探索。 也许您可能只是最终在下一个项目中使用了此框架,或者可能向朋友介绍了。
翻译自:
aurelia
转载地址:http://jwywd.baihongyu.com/