In "Customizing a Directive about a table in AngularJS", a Direcitve about a table is customized. The table is expressed like this:
<table-helper datasource="customers" clumnmap="[{name: 'Name'}, {street: 'Street'}, {age: 'Age'}, {url: 'URL', hidden: true}]"></table-helper>
Above, the value of variable colmnmap is predefined in Scope:
return { restrict: 'E', scope: { columnmap: '=', datasource: '=' }, link:link, template:template };
In AngularJS, there is also a way to assign a value to a Scope variable at runtime, which is to use the $parse or $eval method in the link function.
The presentation of Direcitve is the same as before:
<table-helper-with-parse datasource="customers" columnmap="[{name: 'Name'},...]"></table-helper-with-parse>
Directive is roughly like this:
var tableHelperWithParse = function($parse){ var template = "", link = function(scope, element, attrs){ var headerCols = [], tableStart = '<table>', tableEnd = '</table>', table = '', visibleProps = [], sortCol = null, sortDir = 1, columnmap = null; $scope.$watchCollection('datasource', render); //运行时赋值columnmap columnmap = scope.$eval(attrs.columnmap); //或者 columnmap = $parse(attrs.columnmap)(); wireEvents(); function rener(){ if(scope.datasource && scope.datasourse.length){ table += tableStart; table += renderHeader(); table += renderRows() + tableEnd; renderTable(); } } }; return { restrict: 'E', scope: { datasource: '=' }, link: link, template: template } } angular.module('direcitvesModule') .directive('tableHelperWithParse', tableHelperWithParse);
Let me introduce to you the difference between $parse and $eval
First of all, $parse and $eval are both used to parse expressions, but $parse exists as a separate service. $eval is used as a scope method.
$parse is typically used to set the value of a string expression mapped to a real object. You can also get the value corresponding to the expression directly from $parse.
var getter = $parse('user.name'); var setter = getter.assign; setter(scope, 'new name'); getter(context, locals) // 传入作用域,返回值 setter(scope,'new name') // 修改映射在scope上的属性的值为‘new value'
$eval is scope.$eval, which executes expressions in the current scope, such as: scope.$eval('a+b'); and the a and b here come from scope = {a: 2 , b:3};
Look at the source code and its implementation is
$eval: function(expr, locals) { return $parse(expr)(this, locals); },
You can find that it is also based on $parse, but its parameters have been fixed to this, which is the current scope, so $eval is just a package based on $parse, and is a fast API for $parse.