angular之service与factory的用法

angular之service与factory的用法

直接上代码


<!DOCTYPE html>
<html>
<head>
  <title>Angular JS Forms</title>
</head>
<body>
  <h2>AngularJS Sample Application</h2>
  <div ng-app="mainApp" ng-controller="CalcController">
   <p>Enter a number: <input type="number" ng-model="number" />
   <button ng-click="square()">X<sup>2</sup></button>
   <p>Result: {{result}}</p>
  </div>
  <script src="http://libs.useso.com/js/angular.js/1.2.9/angular.js"></script>
  <script>
   var mainApp = angular.module("mainApp", []);
   mainApp.factory('MathService', function() {   
     var factory = {}; 
     factory.multiply = function(a, b) {
      return a * b 
     }
     return factory;
   }); 

   mainApp.service('CalcService', function(MathService){
      this.square = function(a) { 
      return MathService.multiply(a,a); 
     }
   });

   mainApp.controller('CalcController', function($scope, CalcService) {
      $scope.square = function() {
      $scope.result = CalcService.square($scope.number);
     }
   });
  </script>
</body>
</html>

AngularJS笔记之directive——scope选项与绑定策略

ng-directive

开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细记录的。但是这显然不符合实际开发中的需求,因为实际上,我们经常想要我们的指令能够在特定的情况下与外界进行数据上的交互,这就需要借助绑定策略之手了。

大家知道,当scope选项写为scope:{}这种形式的时候,就已经为指令生成了隔离作用域,现在,我们来看看绑定策略的三种形式:& 、= 、@。

首先是@,它将本地作用域和DOM中的属性值绑定起来(且这个属性的值必须是父级作用域中的),什么意思呢?说的简单一点就是假设你在模板中有个双花括号表达式,然后我们把表达式里的内容和html中指令里特定名字的属性绑定起来,还是不懂?看看下面的代码:

<body ng-app="test">
<div ng-controller="ngs">
      <input type="text" ng-model="haha" />
      <abc for-name="{{ haha }}" for-tem="{{ tem }}"></abc>
</div>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script>
var app=angular.module("test",[]);
app.directive('abc',function(){
       return {
          restrict:'E',
          replace:true,
          template:'<div class="header">冷{{name}}<input type="text" ng-model="name" />{{ aa }}</div>',
          scope:{
              name:'@forName',//属性是传入到template中的值,引号中值是在指令绑定的属性;@是找到的意思(用于字符串)
              aa:"@forTem"//如上解释(限用于字符串)
         }
      }
})
.controller('ngs',function($scope){
       $scope.tem="呵呵";//仅限字符串
});
</script>
</body>

运行结果可想而知,{{ name }}成功地与父控制器中的Name绑定起来了。当然这里也可以这样写

name:’@’ 这样写的话,就默认DOM中的属性名为name了意即 for-name=”{{ Name }}”可简写为name=”{{ Name }}”;其实,另外两个符号=和&也有这样的简写规则,方便起见接下来都使用这种写法。

@到此为止,接下来就是’=’了。=与@的不同点在于,@是针对字符串而用,但=是针对某个对象的引用,

这么说可能不太专业,但就拿上边的例子而言,我们在html中,把Name这个字符串通过一对双花括号传递给for-name属性,但如果我们用了=,这里传入的Name就不应该是一个字符串,而是一个对象的引用。这不是一个很一目了然的概念,所以我用接下来的两个例子诠释它的含义。

<body ng-app="test">
<div ng-controller="ngs">
	<input type="text" ng-model="haha" />
	<abc for-name="haha" aa="tem"></abc>
</div>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script>
var app=angular.module("test",[]);
app.directive('abc',function(){
	return {
		restrict:'E',
		replace:true,
		template:'<div class="header">冷{{forName}}<input type="text" ng-model="forName" />{{aa[0].name}}</div>',
		scope:{
			forName:'=',//属性是指令绑定的属性,且此属性可以传入到template中去;=是等价的意思(用于对象)
			aa:'='//跟上解释
		}
	}
})
.controller('ngs',function($scope){
	$scope.tem=[{name:"哈哈"},{name:"呵呵"}];//类型都可
});
</script>
</body>

这就完成了,其实只不过是加了一点小把戏,把ng-model换成了model而已。

注意到,这个例子中,都是使用对象的引用,而不是单纯的字符串,这也是=可以进行双向绑定的关键。

最后是&符号。它的含义是:对父级作用域进行绑定,并将其中的属性包装成一个函数,注意,是属性,意即,任何类型的属性都会被包装成一个函数,比如一个单纯的字符串,或是一个对象数组,或是一个函数方法,如果是字符串、对象数组和无参的函数,那么可想而知,它们都会被包装成一个无参的函数,若是有参的函数方法则反之,并且我们需要为其传入一个对象。

<body ng-app="test">
<div ng-controller="ngs">
	<abc for-name="fun()"></abc>
</div>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script>
var app=angular.module("test",[]);
app.directive('abc',function(){
	return {
		restrict:'E',
		replace:true,
		template:'<div class="header">冷<input type="button" ng-click="forName()" value="按钮" /></div>',
		scope:{
			forName:'&'//属性是指令绑定的属性,且此属性可以传入到template中去;&(任何类型的属性都会被包装成一个函数)

		}
	}
})
.controller('ngs',function($scope){
	$scope.fun=function(){
		alert(123);
	}
});
</script>
</body>

记录angular之directive指令的用法

1.实例1:从最简单的开始

<html ng-app='app'>
<body>
    <hello></hello>
</body>
<script src="../angular-1.0.3/angular.min.js">
</script> <script src="HelloDirect.js"></script>
</html>

对于以上代码里面的<hello>标签,浏览器显然是不认识的,它唯一能做的事情就是无视这个标签。那么,为了让浏览器能够认识这个标签,我们需要使用Angular来定义一个hello指令(本质上说就是自己来把<hello>这种玩意儿替换成浏览器能识别的那些标准HTML标签)。

来看这段温馨的JS代码:

var appModule = angular.module('app', []);
appModule.directive('hello', function() {
    return {
       restrict: 'E',
       template: '<div>Hi there</div>',
       replace: true
   };
});

以上代码大概看两眼就可以了,不要太在意细节。

然后我们就可以在浏览器里面看到这样的内容:

实际产生的标签结构是这样的:

可以看到,<hello>这个东东已经被<div>Hi there</div>这个标签替换掉了,这也是以上JS代码里面replace:true这行配置的作用,代码里面的template配置 项当然就是我们要的div标签啦,至于restrict:’E’这个配置项的含义,请看下表:

ok,看完上面的表格,对于restrict这个属性相信你已经秒懂了,那么我们来玩儿点花样吧。如果我们需要替换的HTML标签很长,显然不能用 拼接字符串的方式来写,这时候我们可以用templateUrl来替代template,从而可以把模板写到一个独立的HTML文件中。

2.实例2:transclude(变换)


//先看例子,JS代码:
var appModule = angular.module('app', []); 
appModule.directive('hello', function() {
     return { 
         restrict: 'E', 
         template: '<div>Hi there <span ng-transclude></span></div>', 
         transclude: true
    }; 
}); 
//HTML代码:
<html ng-app='app'>
<head> 
     <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
</head> 
<body>
<hello> 
   <br/> 
   <span>原始的内容,</span>
   <br/>
   <span>还会在这里。</span> 
</hello>
<hello> </hello>
</body> 
<script src="../angular-1.0.3/angular.min.js"></script> 
<script src="Transclude.js"></script>
</html> 

运行效果如下:

生成的HTML标签结构如下:

和第一个例子对比,这个例子的JS和HTML代码都略有不同,JS代码里面多了一个transclude: true,HTML代码里面在<hello>内部出现了子标签。

按照我们在第一个例子中的说法,指令的作用是把我们自定义的语义化标签替换成浏览器能够认识的HTML标签。那好,如果我们自定义的标签内部出现了子标签,应该如何去处理呢?很显然,transclude就是用来处理这种情况的。

对于当前这个例子,transclude的作用可以简化地理解成:把<hello>标签替换成我们所编写的HTML模板,但是<hello>标签内部的内容保持不变

很显然,由于我们没有加replace:true选项,所以<hello>标签还在,没有被替换掉。同时,通过这个例子你还还会发现一 个暗藏的属性,那就是浏览器实际上非常智能,虽然它并不认识<hello>这个标签,但是页面没有出错,它只是默默地把这个标签忽略掉了!怎 么样?是不是碉堡了?

你可以自己在上面的JS代码里面加上replace:true,然后再看生成的HTML结构。