开始系统学习一下angular!首先是hello world。根据官网给出的例子,我们一下做出下面这个东西:
<!DOCTYPE html> <html ng-app> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="angular.js"></script> <script> function aaaCtrl($scope) { $scope.name = "World" } </script> </head> <body ng-controller="aaaCtrl"> <h1>Hello {{name}}!</h1> </body> </html>
这里要注意三个地方:
- 必须指定ng-app,如果页面上只有一个应用,可以匿名
- 根据ng-controller划分VM的作用域范围
- 如果应用是匿名的,那么可以直接在全局作用域下定义控制器。控制器为一个函数,用于生成VM, 要求函数名必须以Ctrl结束,并且它的第一个参数必须叫做$scope,否则报错,因为它是基于静态编译,取其toString()来注入各种服务与处理依赖关系。
但上面这种方式基本不可能用于生产环境,我们看下面的例子:
<!DOCTYPE html> <html ng-app="test"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="angular.js"></script> <script> angular.module("test",[]).controller("aaaCtrl",function($scope){ $scope.name = "World" }) </script> </head> <body ng-controller="aaaCtrl"> <h1>Hello {{name}}!</h1> </body> </html>
这时控制器可以随便命名,但第一个参数还是要叫$scope
这是输出结果,其中最重要的是{{}}插值表达式。
{{}}插值表达式相当于knockout的text绑定或avalon的ms-text绑定,当然avalon也可以直接用{{}}插值表达式。它是用于填空文本,当我们要填空HTML时,就要用到另一种绑定了,这在knockout可以用html绑定,avalon可以用{{xxx|html}}或ms-html绑定。在angular, ng-bind-html好像不能用了(看评论,是出BUG了,但至今还没有修复好,此绑定会删提所有内联事件与script标签),但可以用ng-bind-html-unsafe。此外还有一个ng-bind, 它的效果同{{}} 插值表达式。但对于HTML绑定,它都依赖于某一个元素节点,不能做到avalon的{{xxx|html}}的效果。我们可以在这里看实时运行效果,点我
pw:ruby
<!DOCTYPE html> <html ng-app="test"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="angular.js"></script> <script> angular.module("test", []).controller("aaaCtrl", function($scope) { $scope.xxx = "<strong>dddd</strong>" }) </script> </head> <body ng-controller="aaaCtrl"> 1<p>{{xxx}}</p> 2<p ng-bind-html-unsafe="xxx"></p> 3<p ng-bind-html="xxx"></p> 4<p ng-bind="xxx"></p> <hr/> </body> </html>
循环渲染一组数组
<!DOCTYPE html> <html ng-app="test"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="angular.js"></script> <script> //angular会对函数进行静态编译,但那些参数可能被压缩掉, //因此我们需要在函数前添加相关的服务名,这里不能直接用setTimeout,要用$timeout服务, //总之angular这样的隐性知识非常多,是目前最难上手的框架,自己制头造了许多概念 angular.module("test", []).controller("aaaCtrl", ["$scope", "$timeout", function($scope, $timeout) { $scope.friends = [{name: 'John', age: 25}, {name: 'Mary', age: 28}, {name: "Nasami", age: 30}] $timeout(function() { $scope.friends.push({name: "add", age: 10}) }, 1000) }]) //如果不担心被压缩可以这样 //angular.module("test", []).controller("aaaCtrl", function($scope, $timeout) { // $scope.friends = [{name: 'John', age: 25}, {name: 'Mary', age: 28}, {name: "Nasami", age: 30}] // $timeout(function() { // $scope.friends.push({name: "add", age: 10}) // }, 1000) //}) </script> </head> <body ng-controller="aaaCtrl"> I have {{friends.length}} friends. They are: <ul> <li ng-repeat="friend in friends"> [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. </li> </ul> </body> </html>
如果不想用$timeout服务,可以这样写
<!DOCTYPE html> <html ng-app="test"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="angular.js"></script> <script> var a angular.module("test", []).controller("aaaCtrl", ["$scope", "$timeout", function($scope, $timeout) { $scope.friends = [{name: 'John', age: 25}, {name: 'Mary', age: 28}, {name: "Nasami", age: 30}] a = $scope }]) setTimeout(function() { a.friends.push({name: "dsfs", age: 44}) a.$digest()//这个不能漏 }, 1000) </script> </head> <body ng-controller="aaaCtrl"> I have {{friends.length}} friends. They are: <ul> <li ng-repeat="friend in friends"> [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. </li> </ul> </body> </html>
如果用avalon是这样实现的
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="avalon.js"></script> <script> var a = avalon.define("aaa", function(vm) { vm.friends = [{name: 'John', age: 25}, {name: 'Mary', age: 28}, {name: "Nasami", age: 30}] }) setTimeout(function() { a.friends.push({name: "dsfs", age: 44}) }, 1000) </script> </head> <body ms-controller="aaa"> I have {{friends.length}} friends. They are: <ul ms-each-friend="friends"> <li > [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old. </li> </ul> </body> </html>
事件绑定
<!DOCTYPE html> <html ng-app="test"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="angular.js"></script> <script> angular.module("test", []).controller("SpicyCtrl", function($scope) { $scope.spice = 'very'; $scope.chiliSpicy = function() { $scope.spice = 'chili'; } $scope.jalapenoSpicy = function() { $scope.spice = 'jalape?o'; } }) </script> </head> <body ng-controller="SpicyCtrl"> <button ng-click="chiliSpicy()">Chili</button> <button ng-click="jalapenoSpicy()">Jalape?o</button> <p>The food is {{spice}} spicy!</p> </body> </html>
avalon的实现与它大同小异
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="avalon.js"></script> <script> avalon.define("SpicyCtrl", function($scope) { $scope.spice = 'very'; $scope.chiliSpicy = function() { $scope.spice = 'chili'; } $scope.jalapenoSpicy = function() { $scope.spice = 'jalape?o'; } }) </script> </head> <body ms-controller="SpicyCtrl"> <button ms-click="chiliSpicy">Chili</button> <button ms-click="jalapenoSpicy">Jalape?o</button> <p>The food is {{spice}} spicy!</p> </body> </html>
创建一个服务
所谓“服务”者,其实类似于jQuery插件这样的东西,但angular需要以“注入”方式来调用的这些功能(说句不好听的,因此害怕压缩让其静态编译失败,才用到这么绕的方式)
我们看如何创建一个应用。有两种方式,都需要调用angular.module实例的一些方法生成。
var myModule = angular.module(‘app’,[]); //使用实例的factory方法 myModule.factory(‘serviceName’,function() { var someService; //工厂方法体,构建someService return someService; });
angular.module(‘app’,[],function($provide) { //使用$provide服务的factory方法 $provide.factory(‘serviceId’,function() { var someService; //工厂方法体,构建someService return someService; }); });
示例:
<!DOCTYPE HTML> <html lang="zh-cn" ng-app="MainApp"> <head> <meta charset="UTF-8"> <title>services</title> </head> <body> <div ng-controller="MyController"> <input type="text" ng-model="msg"/> <button ng-click="saveMsg()">保存信息</button> <ul> <li ng-repeat="msg in msgs">{{msg}}</li> </ul> </div> <script src="angular.js" ></script> <script type="text/javascript"> var app = angular.module("MainApp", []) app.factory("$notify", ["$window", "$timeout", function(win, timeout) { var msgs = []; return function(msg) { msgs.push(msg); //只有等到消息条数到达3条时,才一起弹出来 if (msgs.length == 3) { timeout(function() { win.alert(msgs.join(" ")); msgs = []; }, 10); } } }]) app.controller("MyController",["$scope", "$notify", function($scope, $notify) { $scope.msgs = []; $scope.msg = "" $scope.saveMsg = function() { $scope.msgs.push($scope.msg);//这里的$scope可改成this $notify($scope.msg); $scope.msg = ""; }; }]); </script> </body> </html>
websocket服务
<!DOCTYPE HTML> <html lang="zh-cn" ng-app="MainApp"> <head> <meta charset="UTF-8"> <title>services</title> </head> <body> <div ng-controller="MyController"> <input type="text" ng-model="msg"/> <button ng-click="saveMsg()">保存信息</button> <ul> <li ng-repeat="msg in msgs">{{msg}}</li> </ul> </div> <script src="angular.js" ></script> <script src="jquery2.02.js" ></script> <script type="text/javascript"> var app = angular.module("MainApp", []) app.factory("$socket", ["$window", "$timeout", function($window, $timeout) { return function(obj) { obj.open = obj.open || function() { console.log("open websocket") } obj.close = obj.close || function() { console.log("close websocket") } obj.timeout = obj.timeout || 1000 obj.maxTime = obj.maxTime || 10 var flag = false; if (flag && $window.WebSocket) { var wsServer = 'ws://' + document.domain + "/" + obj.url.replace(/^//, "") var websocket = new WebSocket(wsServer) websocket.onopen = obj.open websocket.onclose = obj.close websocket.onmessage = function(e) { obj.success(e.data) } websocket.onerror = function(e) { obj.error(e) } } else { var success = obj.success delete obj.success var error = obj.error delete obj.error var errorTime = 0 function callback() { $.ajax(obj).done(function() { success.apply(this, arguments) promise = $timeout(callback, obj.timeout); }).fail(function(a, b) { errorTime++ if (errorTime > obj.maxTime) { arguments[1] = "unconnect" } error.apply(this, arguments) if (errorTime > obj.maxTime || b == "timeout") { $timeout.cancel(promise) obj.close() } else { promise = $timeout(callback, obj.timeout); } }) } var promise = $timeout(callback, obj.timeout); obj.open() } } }]) app.controller("MyController", ["$scope", "$socket", function($scope, $socket) { $scope.msgs = []; $scope.msg = "" $scope.saveMsg = function() { $socket({url: "/resource/region/list", success: function() { console.log(arguments) }, error: function() { console.log(arguments) }}) }; }]); </script> </body> </html>