angularjs的重要部分

angularjs的重要部分

        如今前端框架出現的愈來愈多,幾年前的angularjs已近處於被淘汰的地步了。可是angularjs有幾樣東西是頗有借鑑價值的,不管之後的ECMAScript的標準如何發展,這幾樣東西都是咱們須要掌握的技巧。例如:依賴注入和指令
javascript

一、Dependecy Injection

        依賴注入在java中大量使用,或者說是java出名的開源框架都會用到。java是經過JVM的解釋器特性,將class在內存中解析爲<class>的數據結構,經過反射來實現依賴注入。咱們只須要註冊依賴名稱、依賴類關係、獲取依賴類就能夠很方便的使用。而javascript也有JVM解釋器的相似實現,或者說javascript的解釋器更加符合一個動態語言的工做方式,更加方便的使用依賴注入功能。
html

        咱們正常使用:代碼耦合過高
前端

function animal(name){
		this.name=name;
	}
	animal.prototype.eat = function(food){
		console.log(" I am a "+this.name+" , I'am eating "+food);
	}
	
	function keep(){
		this.animal=new animal("老虎");
		this.feed=function(food){
			this.animal.eat(food);
		}
	}
	//使用
	var keep1=new keep();
	keep1.feed("肉");

       外部注入:java

function keeper(animal){
		this.animal=animal;
	}
	keeper.prototype.feed =  function(food){
		this.animal.eat(food);
	}
	
	//外部注入
	var pig=new animal("pig");
	var keeper1=new keeper(pig);
	keeper1.feed("青菜");
	
	var keeper2=new keeper(pig);
	keeper1.feed("土豆");

      angularjs裏面的的依賴注入:從下面的moduleInstance裏面看出,模塊的服務都放在$provide裏面
angularjs

每個模塊的結構:
var moduleInstance = {
          // Private state
          _invokeQueue: invokeQueue, //執行隊列
          _configBlocks: configBlocks,//配置塊
          _runBlocks: runBlocks,    //運行塊
          requires: requires,    //須要的依賴
          name: name,            //名稱
          provider: invokeLater('$provide', 'provider'),    
          factory: invokeLater('$provide', 'factory'),
          service: invokeLater('$provide', 'service'),
          value: invokeLater('$provide', 'value'),
          constant: invokeLater('$provide', 'constant', 'unshift'),
          animation: invokeLater('$animateProvider', 'register'),
          filter: invokeLater('$filterProvider', 'register'),
          controller: invokeLater('$controllerProvider', 'register'),
          directive: invokeLater('$compileProvider', 'directive'),
          config: config,
          run: function(block) {
            runBlocks.push(block);
            return this;
          }
        };

        angularjs的$provider和$injector:數組

            一、其中$provider是$injector內部的一個對象,用來存放咱們創造的服務。也能夠經過上面的moduleInstance看出,每個咱們建立的module都會有$injector來存放$provide,而後$provide來存放咱們建立的服務。瀏覽器

providerCache = {
   $provide: {
       provider: supportObject(provider),
       factory: supportObject(factory),
       service: supportObject(service),
       value: supportObject(value),
       constant: supportObject(constant),
       decorator: decorator
    }
}
函數
  function provider(name, provider_) {
    assertNotHasOwnProperty(name, 'service');
    if (isFunction(provider_) || isArray(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
    }
    return providerCache[name + providerSuffix] = provider_;
  }
 
 使用方式:
 $provide.provider('test',function(){
        this.name="test";
        this.$get=function(){
            return name;//閉包
        }
 });
 app.controller('myCtrl',function($scope,test){
     $scope.test=test;
 });

            二、$injector是一個注入器,也能夠說是用來查詢服務的工具類。也是每一個module都有一個$injector(包括angularjs自己)用來存放$provide,而$provide則使咱們真正的用來存放service的對象。
前端框架

angular.module('myModule2',[]).
factory('myService',function(){
	return {
		test:function(text){
			console.log('test the injectors:'+text);
		}
	}
});
//獲取myModule2的injector
var injector = angular.injector(['myModule2']);
//獲取myService裏面的函數
var test=injector.get('myService');
//使用
test.test("hello injector");

二、Directive

        指令是Angularjs應用裏面重要的一部分。經過HTML的組合製做一個HTML元素以及綁定在元素上的angularjs的服務。
數據結構

        a、元素建立(DOM的特性):
閉包

restrict:使用限制
(
    E:元素:看成元素使用
    A:單作attribute使用
    C:看成class使用
    M:單作註解使用
)
        
templateUrl/template:模版,利用HTML組裝

replace:是否替換換掉HTML顯示,在瀏覽器的ELEMENT裏面顯示新元素

priority:指令的優先級,當多個指令執行的時候,用來執行complie函數裏面的方法的先後順序。

    b、對外的scope:(子類和父類通訊橋樑,要想在指令中使用MVVM的功能,必須執行scope類型)

scope是angularjs操做的核心,這裏的scope是指指令裏面的scope和父類的scope的聯繫
{
    flase:共享父類的做用域、子類/父類修改一個都改動
    true:繼承父類的做用域,可是新建獨立做用域。在指令初始化的時候使用父類的值,以後子類修改不會改變父類的值
    {}:新建一個做用域,單獨做用。在使用scope:{}時候,能夠經過屬性擴展來解決,父類的做用域和指令scope做用域通訊。由於不是全部的數據都須要通訊,這就須要區別對待。
     scope:{
         myName : '=',    //綁定到父類scope的myName上(屬性雙向綁定)
         mySexy : '=mySexyAttr',    //綁定到父類scope的mySexyAttr上(屬性雙向綁定)
         myAge : '@',        //綁定到父類scope的myAge 上(屬性單向綁定,子類變父類不變,傳值用{{}})
         myAge1 : '@myAgeAttr' //綁定到父類scope的myAgeAttr 上(屬性單向綁定,子類變父類不變,傳值用{{}})
         onSay : '&'       //綁定到父類onSay 的方法上(方法綁定)
         onSay1 : '&onSayFunc'   //綁定到父類onSayFunc 的方法上(方法綁定)
     }
}

    c、對外參數require:指令之間的通訊橋樑

一、若是須要組合指令的時候使用
require:指令或者指令數組
用法1、
require : '^?test'
用法二
require : ['^?test1','test2']

?:尋找指令名稱,若是沒找到則報錯
^:在指令尋找方法名,並向父類查找。若是沒有^,則只在該指令中查找

    d:行爲參數:指令綁定的服務

一、controller:先於link執行的方法,還能夠經過require傳遞給其它的指令使用。(通常不用)
controller:function($scope,$element,$attrs){
    $scope:做用域
    $element:對應的元素
    $attrs:元素上的屬性
    $transclude:
}

二、link:後於controller執行的函數,和不一樣的controller區別不大。(優先使用)
link:function(scope,elem,attrs,ctrl){
    scope:做用域
    elem:對應的元素
    attrs:元素上的屬性
    ctrl:從require上傳遞過來的指令數組
}

三、bug避免在使用自定義的時候,若是字符串有大小寫,要加如-
		myApp.directive('circleUtils', function(){
			return {
				restrict : 'E',
				replace : false,
				transclude: true,
				scope : {
					outerStyle : '@outerStyle',
					inlineStyle : '@inlineStyle',
					degree : '@degree'
				}
使用
<circle-utils outer-Style="{{outerStyle}}" degree="{{degree}}" inline-Style="{{inlineStyle}}"></circle-utils>

    案例()

<!DOCTYPE html>
<html ng-app="myModule">
<head>
<script src="angular.js"></script>
</head>
<body ng-controller='myController'>
	<div>
		<div style="background-color:blue">圈圖</div>
		<hr>
		<div ng-style="outerStyle">
			<div ng-style="inlineStyle" align="center">{{degree*100}}%</div>
		</div>
		<hr/>
		<div >
			<circle-utils outer-Style="{{outerStyle}}" degree="{{degree}}" inline-Style="{{inlineStyle}}"></circle-utils>
		</div>
	</div>
</body>
	<script >
		var myApp = angular.module('myModule',[]);
		myApp.controller('myController',function($scope){
			$scope.degree=0.8;
			$scope.width=80;
			$scope.outerStyle={
				"width":""+$scope.width+"px",
				"background-color":"red",
				"height":"20px"
			};
			$scope.inlineStyle={
				"width":""+($scope.degree*$scope.width)+"px",
				"background-color":"blue",
				"height":"20px"
			};
		});
		myApp.directive('circleUtils', function(){
			return {
				restrict : 'E',
				replace : false,
				transclude: true,
				scope : {
					outerStyle : '@outerStyle',
					inlineStyle : '@inlineStyle',
					degree : '@degree'
				},
				template : '<div ng-style="{{outerStyle}}"><div ng-style="{{inlineStyle}}" align="center">{{degree*100}}%</div></div>',
				link : function(scope ,elem ,attrs ,ctrl){
					console.log(scope.outerStyle);
					console.log(scope.inlineStyle);
				}	
			}
		});
	</script>
</html>

    效果

相關文章
相關標籤/搜索