学游者

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

angularjs的重要部分

现在前端框架出现的越来越多,几年前的angularjs已近处于被淘汰的地步了。但是angularjs有几样东西是很有借鉴价值的,无论以后的ECMAScript的标准如何发展,这几样东西都是我们需要掌握的技巧。例如:依赖注入和指令

1、Dependecy Injection

依赖注入在java中大量使用,或者说是java出名的开源框架都会用到。java是通过JVM的解释器特性,将class在内存中解析为的数据结构,通过反射来实现依赖注入。我们只需要注册依赖名称、依赖类关系、获取依赖类就可以很方便的使用。而javascript也有JVM解释器的类似实现,或者说javascript的解释器更加符合一个动态语言的工作方式,更加方便的使用依赖注入功能。

我们正常使用:代码耦合太高

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("肉");

外部注入:

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里面

每一个模块的结构:
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:

1、其中$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;
 });

2、$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");

2、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:指令之间的通信桥梁**

1、如果需要组合指令的时候使用
require:指令或者指令数组
用法一、
require : '^?test'
用法二
require : ['^?test1','test2']

?:寻找指令名称,如果没找到则报错
^:在指令寻找方法名,并向父类查找。如果没有^,则只在该指令中查找

**    d:行为参数:指令绑定的服务**

1、controller:先于link执行的方法,还可以通过require传递给其它的指令使用。(一般不用)
controller:function($scope,$element,$attrs){
    $scope:作用域
    $element:对应的元素
    $attrs:元素上的属性
    $transclude:
}

2、link:后于controller执行的函数,和不同的controller区别不大。(优先使用)
link:function(scope,elem,attrs,ctrl){
    scope:作用域
    elem:对应的元素
    attrs:元素上的属性
    ctrl:从require上传递过来的指令数组
}

3、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>

效果

posted on 2024-06-18 23:35  学游者  阅读(15)  评论(0)    收藏  举报