首先看看官方关于$parse的api
- $parse
- 作用:将一个AngularJS表达式转换成一个函数
- Usage
$parse(expression)
- arguments
expression
:需要被编译的AngularJS语句
- returns
func(context,locals)
- arguments
简单说:$parse服务可以将一个表达式转换为一个函数。这个函数可以被调用,其中的参数是一个上下文对象,通常来说是作用域。
另外,通过$parse的表达式返回的这个函数有一个assign属性。这个assign属性也是一个函数,它可以用来在给定的上下文中改变这个表达式的值。
尝试应用这个服务
T1:在第一个例子中,我们先解析一个简单的表达式:
代码如下:
<div ng-app="MyApp"> <div ng-controller="MyController"> <h1>{{ParsedValue}}</h1> </div> </div>
angular.module("MyApp",[]) .controller("MyController",function($scope,$parse){ var context = { name: "dreamapple" }; // 因为这个解析的语句中含有我们想要解析的表达式, // 所以要把不相关的用引号引起来,整体然后用+连接 var expression = "'Hello ' + name"; var parseFunc = $parse(expression); $scope.ParsedValue = parseFunc(context); });
expression:是我们想要解析的表达式
context:就是一个解析表达的上下文环境(个人理解)
parseFunc:就是解析以后返回的函数
angular.module("MyApp",$parse){ var context = { name: "dreamapple" }; // 因为这个解析的语句中含有我们想要解析的表达式, // 所以要把不相关的用引号引起来,整体然后用+连接 var expression = "'Hello ' + name"; var parseFunc = $parse(expression); //false console.log(parseFunc.literal); //false console.log(parseFunc.constant); //undefined console.log(parseFunc.assign); //hello console.log(parseFunc()); //function (self,locals) { // return fn(self,locals,left,right); // } console.log(parseFunc); $scope.ParsedValue = parseFunc(context); });
从控制台我们可以知道,返还的parseFunc是一个函数,其中它的literal和constant属性都是false,而且parseFunc()返回的是没有加入函数运行上下文的值即"Hello"。
T2:在第二个例子中,我们来再次使用$parse服务,来解析一个输入框中的值:
<div ng-app="MyApp"> <div ng-controller="MyController"> <input type="text" ng-model="expression" /> <div>{{ParsedValue}}</div> </div> </div>
angular.module("MyApp",$parse){ $scope.$watch("expression",function(newValue,oldValue,context){ if(newValue !== oldValue){ var parseFunc = $parse(newValue); $scope.ParsedValue = parseFunc(context); } }); });
我们使用$watch监测input输入框的变化,每当输入框中的表达式的值发生变化时,我们都会解析它,我们可以尝试向输入框中输入"1+1",然后就会看到下面显示2。
T3:我们会在第三个实例中比较深入地使用$parse服务
<div ng-app="MyApp"> <div ng-controller="MyController"> <div>{{ParsedValue}}</div> </div> </div>
angular.module("MyApp",$parse){ $scope.context = { add: function(a,b){return a + b;},mul: function(a,b){return a * b} } $scope.expression = "mul(a,add(b,c))"; $scope.data = { a: 3,b: 6,c: 9 }; var parseFunc = $parse($scope.expression); $scope.ParsedValue = parseFunc($scope.context,$scope.data); });
我们可以看到结果是45,我们大致可以这样理解,$parse服务根据$scope.context中提供的上下文解析$scope.expression语句,然后使用$scope.data数据填充表达式中的变量注意,如果把$scope.expression中的c换成4,那么结果就是30,所以得到45结果。
T4:第四个实例是使用$parse服务获取和修改自定义指令中属性的值:
<div my-attr="obj.name" my-directive>testing</div> app.directive('myDirective',function($log,$parse){ return function(scope,elem,attrs){ //解析"my-attr属性值到一个函数中" var model = $parse(attrs.myAttr); //model现在是一个函数,可以调用它来获取表达式的值 //下面这行代码将会输出作用域中obj.name的值 $log.log(model(scope)); elem.bind('click',function(){ //'model.assign'也是一个函数,它用来更新表达式的值 model.assign(scope,'New name'); scope.$apply(); }) } });上面的例子可以充分体现我们为什么需要$parse服务。如果属性值是name,那么我们完全可以不用$parse,只用scope[attrs.myAttr]即可。但是在上面的例子中,方括号并不管用。