angularjs概览(大概其的翻译)

angularjs是由谷歌提供的一套框架,这套框架以其灵活多变,组织结构清晰,便于测试等优势很快就为广大开发爱好者关注。框架本事基于MVC架构,(是的,和reactjs这种纯粹的view框架是完全一样的东西,其实和vuejs这种是一类的,但是实际上vuejs是根据这个来的说)。此框架主要用于在客户端开发富互联网应用。(这个称谓之前叫做富媒体应用,现在改名字了)

angularjs只是个前端框架,提供了数据绑定,数据模型验证,模板页,单页内路由导航的技术,一般使用ajax方法和后端进行通信,通信结构多数情况是是纯粹的json,有时候为了方便我们把后端做成只提供json的restful框架。

1.0 此篇文章包含那些内容

此篇文章包含angularjs入门的方方面面,我觉的特别好所以才试着根据它来扩展的。包括控制器和作用域(一般这两件事是入门概念),services, models, templates, directives, filters, modules and configurations

2.0 Web应用(不是Web网站)

这两者是完全不同的,Web应用的特点是基于MVC框架,用JavaScript编写业务逻辑,使用数据绑定和模板页来进行页面的呈现,以及用ajax从服务器拿到数据,一般这个数据载体是json。这套逻辑的特点是整个应用程序像是一个应用框架,而不是逻辑紧密的页面和数据呈现。您可以会议一下早些年那些黏糊糊的html和服务器端代码混写的时代,以及点击一个按钮就要全页刷新,每个前置页面都得在服务器端配置一个handle页面的时代,那玩意叫做Web网站。

这种web应用的最大优势就是可以把每个页面分离之后单独运行,以及可以不在浏览器内运行。只要有个桌面解析html和javascript的环境就行。实际上这一套框架在移动端可以使用phonegap或者cordova进行打包,或者在桌面端用http://electron.atom.io/ 来进行打包,实现跨平台应用,所以angularjs这种框架实际上应用场景很广泛。

3.0 工作方式是怎样的?

angularjs的工作核心就是把逻辑和表示层分离。客户端通过使用directives, filters, bindings and binding-specific operations.这些技术来实现表示层的样式和基本呈现方法,而 Controllers, Services and Models则被用于进行逻辑封装和数据呈现统一。以及这样做的最大好处就是服务器端不用生成任何HTML了。(几乎)

以及和所有的MVC架构差不多,angularjs也可以劫持地址栏的地址,把它们拆分成不同的入口,把每个入口用不同的controller来处理,这样就用完全的前端模块化方法来处理业务逻辑了。不需要后端参与,后端只负责提供数据服务了。

4.0下面我们开始了

<script type=“text/javascript” src=“/path/to/angular/angular.js”>script> <script type=“text/javascript” src=“/path/to/angular/angular-resource.js”>script>

一般来说我们使用bower来安装依赖包,我本来是CDN的倡导者,建议大家使用CDN来获取公共js,但是这些年,情况越来也不好,好多CDN居然敢在公共库里插广告….

5.0模块化入口

angularjs的模块化类似于其它变成语言的名字空间,在这上面加入了依赖注入和错误追踪。

模块化的语法如下,HTML页面里

<html data-ng-app=“YOUR_APP_NAME”>

JavaScript里面

var App = angular.module(‘YOUR_APP_NAME’, [‘ngResource’]);

模块名称要对应,这是程序入口,每个模块管理自己的作用域,以及错处理中错误代码的位置。

模块创建的第二个参数,也就是数据是一个依赖项,意思是该模块的创立依赖那些第三方模块(其实哪儿有那么些个第三方模块,一大半情况下都是使用angularjs自己的附加功能,比如常见的rescource这种http请求的高级版,或者router这种为单页应用设计的路由模块,以及还有animation这种我一直都知道但是没有艺术细胞也不知道怎么用的模块,angularjs在第一代的时候很像哥几个为了趁手一点弄个了小功能,后来不断加上插件,最后变成一个有点臃肿但是还能看的类库集合,你如果从一开头就关注它,那么就可以很容易的理解为什么会忽然多出一些看起来奇怪的模块,因为那些都是功能上的新特性。但是angularjs2就完全不一样了,一开头就开始弄的特正规,以至于写个hello world都要搞半天。这事咱们以后再聊。)

模块创立之后,所有的工作组件,比如routes, models, filters and directives都依赖于它。

顺便,模块不能重名这种小事您应该知道吧….

6.0数据绑定和表达式(这就是angularjs一开始就让人觉的很赞的魔法)

绑定动作和表达式的目标就是把数据从js里放到HTML中,应该说避免了HTML和后端代码的混编,但是把HTML和JavaScript混编在一起了。很多架构觉的这样不优雅,比如reactjs就觉的干嘛这么讨厌,直接用JavaScript生成表示层元素类实例,接着渲染一下不就好了,这样想用html渲染就用html渲染,想用原生平台渲染,比如ios或者android上用原生渲染就原生渲染直接出原生应用。

我无意评价那种更好,只能说,看情况吧。

angularjs的表达式里能做这些数据的渲染和绑定操作。data binding, two-way data binding, conditionals, for in and foreach loops, model binding and so on.

举个例子:

<div class=“records” data-ng-repeat=“record in records | orderBy:orderProp”> <h5> {{ record.title }} h5> div>

这里的records在一个叫做$scope的作用域下面,关于作用域,你可以理解为每个controller都单独封装的一个变量空间,以及作用域对象还有一个全局的,在模块下面,每个模块单的有一个,用来管理那些通用的内容,但是(敲黑板)我们一般建议大家在不要使用全局对象,而是把要全局弄的工作封装到services中,给大家提供服务。这件事儿后面再聊。

针对上面的例子的数据是长这样的

$scope.records = [ { title : ‘one’ }, { title : ‘two’ }, { title : ‘three’ } ];

所以你能看出来,这里顺序显示了三条记录的中的title列,然后顺序是根据一个叫做orderprop的内容来做的,这个orderprop可能来自于某个文本控件或者自定义的filter,至于什么是filter,你可以理解为某个可以处理数据的对象,专门用来解决绑定数据的呈现问题,我们在后面会告诉你怎么写这个对象,顺便filter是跟着模块走的,属于每个模块自己的一个内建对象。

7.0依赖注入

这是angularjs执行的核心,前面的绑定的代码已经告诉大家可以通过在html中写一些符号加入JavaScript变量,然后浏览器运转的时候这些变量的值会被取出并送显,这件事能玩的转全靠依赖注入,它的工作方式就是监视html中那些你加入的标记,然后处理它们。

它可以处理你在angularjs中写到的几乎所有内容。controllers, module configuraitons, directives, filters, resources and routes

下面是一段依赖注入的代码

//the controller definition App.controller(‘Ctrl’, [‘$scope’, ‘$http’, ‘$location’, function($scope, $http, $location) { /* to change the URL after something has happened then you can use $location */ $location.path(‘/path/to/new/page’); }]);

依赖注入有什么好处呢,我看好处就是可以把代码彻底隔离,因为有了依赖注入,实际上每个angularjs中的代码都可以写作一般的工程,这样一来你就可以很方便的进行代码编写而不必关心UI了,进一步的你可以在完全没有UI的情况下测试angualrjs里的所有代码。我们后面也许会聊到mocha

这是一个用来做测试的框架,在写angularjs的时候我们通常使用它来进行代码的功能测试。

8.0路由功能

路由功能一方面处理用户的Http请求里的url把其中的一些部分拆分出来作为controller入口,另一部分作为参数传递给这个函数入口,目的通常是为了单页应用框架使用的。单页应用框架中是在一个物理页面中放多个webview,这么做多半是为了打包。无论是打包成为移动应用(phongap或者cordova),还是为了减少请求次数把网页打包(webpack),以及甚至打包作为一个桌面应用(electron),目前打包都特别流行。

router代码如下,以及router需要单独引入ngrouter模块

App.config([‘$routeProvider’, function($routes) { $route.when(‘/’,{ templateUrl : ‘/templates/home.html’, controller : HomeCtrl }); $route.when(‘/register’,{ templateUrl : ‘/templates/register.html’, controller : RegisterCtrl }); $routes.otherwise({ redirectTo : ‘/’ }); }]);

可以看出ngrouter模块直接依赖于主模块。

一般入口的router包含各个webviewe也就是不同的controller,然后每个controller的代码在单独的js里,里面一般都是针对这个webview里面提供的接受参数进行处理的代码,也就是说,每个controller里面也可能有单独的router对象。

9.0控件和作用域

代码如下

app.controller(‘SomeCtrl’, [‘$scope’, function($scope) { $scope.value = ‘some value’; }]);

作用域对象作为一个参数给控件。

然后作用域对象这么用。

<div class="header">{{ title }}div>
$scope.title = 'this is awesome';
<div class="header">this is awesomediv>

9.1 强制更新scope

部分情况下可能angularjs没有办法意识到变量已经发生变化了,于是我们需要用apply来告知它。

//lets say you have

{{ someVar }}

inside your HTML.

$scope.someVar = ‘value’; //if a scope digestion is already going on then it will get picked up and you won’t //have to call the $scope.$apply() method if(!$scope.$$phase) { //this is used to prevent an overlap of scope digestion $scope.$apply(); //this will kickstart angular to recognize the change }

9.2 rootscope

如果你打算跨过controller的分野,直接在所有作用域共享内容(一般是计数变量或者方法,不过我们一般建议方法还是用services)您可以这么干。

App.run([‘$rootScope’, function($rootScope) { $rootScope.sharedFunction = function() { … }; }]);

9.3 controller的使用

在HTML中声明一个

<div data-ng-controller=“SomeCtrl”>div>

在router中声明一个

$routes.when(‘/some/path’,{ controller: ‘SomeCtrl’, templateUrl: ‘/templates/controller.html’ });

10 services(总算说到这个了)

这个东西就是公用方法,在不同地方都可以使用到的方法

定义以及在各个地方使用的例子如下

//define the service

App.factory(‘myService’, [‘myOtherService’, ‘$location’, function(myOtherService, $location) { return function(input) { //do something with the input using the myOtherService or the $location objects. return input; }; }]);

//use the service within the controller

App.controller(‘HomeCtrl’, [‘$scope’, ‘myService’, function($scope, myService) { var input = ‘123’; input = myService(input); }]);

//use the service a directive

App.directive(‘myDirective’, [‘myService’,function(myService) { return { link: function($scope, element, attrs) { var input = ‘123’; input = myService(input); } } }]);

11.模型

模型基本上和其它应用架构的差不多,就是提供服务用的

下面是个例子

App.factory(‘ModelName’, [‘$resource’, function($resource) { $resource.url(‘/path/to/model/controller/:id’,

{ id : ‘@id’, //this binds the ID of the model to the URL param },

{ query : { method : ‘GET’, isArray : true }, //this can also be called index or all save :

{ method : ‘PUT’ }, //this is the update method create :

{ method : ‘POST’ }, destroy :

{ method : ‘DELETE’ } } }]);

调用也很简单

App.controller(“ShomeCtrl”, [‘ModelName’, ‘$scope’, function(ModelName, $scope) { //now you can use ModelName to do your business }]);

定义之后就可以在controller作用域里随便用了,就和本地操作一样了。

//list all the records on the page var results = ModelName.query({ search : ‘all’ }, onSuccessFn, onFailureFn); //get a specific record /* onSuccessFn and onFailureFn are optional callback functions where you can further customize the response */ var record = ModelName.get({ id : 123 }, onSuccessFn, onFailureFn); //create a new ModelName record var record = new ModelName(); //update that record record.someAttr = ‘someValue’; record.$save(); //or if you prefer to submit your data in a different way ModelName.save({ id : record.id },{ somePostObject : { attr1 : ‘value’, attr2 : ‘value2’ } }); //destroy the record (and include a token) record.destroy({ token : record.token });

下面来个完整点的例子(官方向导里面的)

先定义模块

angular.module('core.phone', ['ngResource']);
接着实现模块
angular.
  module('core.phone').
  factory('Phone', ['$resource',
    function($resource) {
      return $resource('phones/:phoneId.json', {}, {
        query: {
          method: 'GET',
          params: {phoneId: 'phones'},
          isArray: true
        }
      });
    }
  ]);

再封装一把
angular.module('core', ['core.phone']);
调用者
angular.module('phoneList', ['core.phone']);
调用者组件
angular.
  module('phoneList').
  component('phoneList', {
    templateUrl: 'phone-list/phone-list.template.html',
    controller: ['Phone',
      function PhoneListController(Phone) {
        this.phones = Phone.query();
        this.orderProp = 'age';
      }
    ]
  });
这里面
this.phones = Phone.query();
就是调用模块服务,加载了json文件。

12.0 directives

这东西主要用来封装代码和复用代码使用的。一般来说就是在当前HTML作用域里创建一个新的,可复用的作用域代码,然后复用和隔离。

angular.directive(‘myDirective’,function($compile) { return { //(optional) the contents of this template can be // downloaded and constructed into the element templateUrl : ‘/path/to/some/template.html’, //whether or not to replace the inner //data within the element replace : true, //this is where your magic happens link : [‘$scope’, function($scope) { $scope.title = ‘…’; }] }; });

顺便一提,这里的scope是可以和包含它的controller共享的,当然也可以隔离,也可以指定从里面可以访问外面等等,具体可以参考ppt。总之这个东西是用来共享变量的。

13.0 filters

这是一个可复用的方法用于在绑定的时候对输出数据进行过滤

App.filter(‘myUppercase’, function(data) {

for(var i=0; i < data.length; i++) {

data[i].title = data[i].title.toUpperCase(); }

return data; });

在HTML中使用很方便

<div data-ng-repeat=“for record in records | filter:myUppercase”></div>

直接用也很方便

var values = [‘one’,‘two’,‘three’]; values = $filter(‘myUppercase’)(values);

14.HTML5的API介入

App.config([‘$locationProvider’, function($location) { $location.html5Mode(true); //now there won’t be a hashbang within URLs for browers that support HTML5 history }]);

后面几个我觉的也就那意思,以及第二篇也很好。

https://www.yearofmoo.com/2012/10/more-angularjs-magic-to-supercharge-your-webapp.html

 

 

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s