Notes: parse 和 eval 等service之前都有一个$ 美元符号

parse  angular中重要指令介绍( eval,  parse和 compile)  Advanced Angular: parse

$parse

----------------------------------------------------------------------------------------------------

$parse

$parse服务是将一个Angular expression转化为一个函数

Converts Angular expression into a function.

var getter = $parse('user.name');
var setter = getter.assign;
var context = {user:{name:'angular'}};
var locals = {user:{name:'local'}}; expect(getter(context)).toEqual('angular');
setter(context, 'newValue');
expect(context.user.name).toEqual('newValue');
expect(getter(context, locals)).toEqual('local');

Returns

调用$parse后返回一个函数

function(context, locals)
a function which represents the compiled expression:

  1. context – {object} – an object against which any expressions embedded in(angular表达式所在的上下文) the strings are evaluated against (typically a scope object).
  2. locals – {object=} – local variables context object, useful for overriding values in context(locals可以覆盖掉context里面的值).

The returned function also has the following properties:

  1. literal – {boolean} – whether the expression's top-level node is a JavaScript literal.
  2. constant – {boolean} – whether the expression is made entirely of JavaScript constant literals.
  3. assign – {?function(context, value)} – if the expression is assignable, this will be set to a function to change its value on the given context(改变表达式所在的上下文中的值).

----------------------------------------------------------------------------------------------

Advanced Angular: $parse

If you want to step up in your AngularJS knowledge, $parse is one of the most important services that you should know about. It is used in most of the directives, and opens up your imagination to a new set of possibilities.

So, what does it do? Let’s start with a place we all well know: ngClick.

ngClick directive, takes an expression, and executes the expression when the directive element is clicked. So, how does it work internally? Yep, you guessed it: with $parse.

$parse takes an expression, and returns you a function. When you call the returned function with context(带着上下文作为第一个参数) (more on that later) as first argument, it will execute the expression with the given context.

Let’s see it with an example:

function MyService($parse) {
  var context = {
    author: { name: 'Umur'},
    title: '$parse Service',
    doSomething: function (something) {
      alert(something);
    }
  };
  var parsedAuthorNameFn = $parse('author.name');
  var parsedTitleFn = $parse('title');
  var parsedDoSomethingFn = $parse('doSomething(author.name)');
 
  var authorName = parsedAuthorNameFn(context);
  // = 'Umur'
  var parsedTitle = parsedTitleFn(context);
  // = '$parse Service'
  var parsedDoSomething = parsedDoSomethingFn(context);
  // shows you an alert 'Umur'
}

So this is very cool, we can evaluate strings with a context safely. Let’s write a very basic myClick directive.

angular.module('my-module', [])
  .directive('myClick', function ($parse) {
    return {
      link: function (scope, elm, attrs) {
        var onClick = $parse(attrs.myClick);
        elm.on('click', function (e){
          // The event originated outside of angular,
          // We need to call $apply
          scope.$apply(function () {
            onClick(scope); // 传递了一个上下文参数
          });
        });
      }
    }
});

See, the pure javascript object turns out to the our scope!

This works, but if you look at the docs of ngClick, it lets us to inject $event object to the function. How does that happen? It is because the parsed function accepts an optional second argument for additional context.

在angular的ngClick中,是可以传递$event参数的,我们这里是自定义了一个参数,传递了进去

We have access to event object in the click callback, and we can just pass this through.

angular.module('my-module', [])
  .directive('myClick', function ($parse) {
    return {
      link: function (scope, elm, attrs) {
        var onClick = $parse(attrs.myClick);
        elm.on('click', function (e){
          // The event originated outside of angular,
          // We need to call $apply
          scope.$apply(function () {
            onClick(scope, {$event: e});// 构造了一个自己的$event对象,传递了进去
          });
      });
    }
  }
});

If you don’t need to pass additional context, you can save some bytes and remove code of the code. Here is a way to do it cooler. How does it work exercise it left to the reader. Please leave a comment if you think you’ve found the answer!

angular.module('my-module', [])
  .directive('myClick', function ($parse) {
    return {
      link: function (scope, elm, attrs) {
        var onClick = $parse(attrs.myClick);
        elm.on('click', function (e) {
          scope.$apply(onClick);
        });
      }
    }
});

$eval

Angular.js: How does $eval work and why is it different from vanilla eval?

$eval and $parse don't evaluate JavaScript; they evaluate AngularJS expressions.( $eval$parse处理的不是js表达式,而是Angular表达式)

The linked documentation explains the differences between expressions and JavaScript.

Q: What exactly is $eval doing? Why does it need its own mini parsing language?

From the docs:

Expressions are JavaScript-like code snippets that are usually placed in bindings such as {{ expression }}. Expressions are processed by $parse service(内部调用$parse服务).

It's a JavaScript-like mini-language that limits what you can run (e.g. no control flow statements, excepting the ternary operator) as well as adds some AngularJS goodness (e.g. filters).

Q: Why isn't plain old javascript "eval" being used?

Because it's not actually evaluating JavaScript. As the docs say:

If ... you do want to run arbitrary JavaScript code, you should make it a controller method and call the method. If you want to eval() an angular expression from JavaScript, use the $eval() method.

The docs linked to above have a lot more information.

($parse vs $eval)

$parse/$eval和$observe/$watch如何区分

$parse和$eval

首先,$parse跟$eval都是用来解析表达式的, 但是$parse是作为一个单独的服务存在的。$eval是作为scope的方法来使用的。
$parse典型的使用是放在设置字符串表达式映射在真实对象上的值。也可以从$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 即scope.$eval,是执行当前作用域下的表达式,如:scope.$eval('a+b'); 而这个里的a,b是来自 scope = {a: 2, b:3};
看看源码它的实现是

$eval: function(expr, locals) {
return $parse(expr)(this, locals);
},

可以找到它也是基于$parse,不过它的参数已经被固定为this,就是当前的scope,所以$eval只是在$parse基础上的封装而已,是一种$parse快捷的API。

angular $parse $eval parse VS eval的更多相关文章

  1. AngularJS $eval $parse

    $eval $parse都可以解析或计算Angular表达式的值. 一.$parse 是一个独立的可以注入的服务,注入就可以使用,它返回一个函数,我们需要显式将表达式求值的上下文传递给该函数.$par ...

  2. JSON.parse与eval的区别

    JSON.parse与eval和能将一个字符串解析成一个JSON对象,但还是有挺大区别. 测试代码 var A = "{ a: 1 , b : 'hello' }"; var B ...

  3. JSON.parse和eval的区别

    JSON.parse和eval的区别 JSON(JavaScript Object Notation)是一种轻量级的数据格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是Jav ...

  4. 浅谈AngularJS中的$parse和$eval

    AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. 总的来说,$parse和$eval都是作用于Ang ...

  5. JSON.stringify()、JSON.parse()和eval(string)

    1.JSON.stringify()用于从一个对象解析出字符串,eg: var obj = {"name":"奔跑的蜗牛","age":&q ...

  6. 用JSON.parse和eval出现的问题

    json格式非常受欢迎,而解析json的方式通常用JSON.parse()但是eval()方法也可以解析,这两者之间有什么区别呢? JSON.parse()之可以解析json格式的数据,并且会对要解析 ...

  7. 转;说说AngularJS中的$parse和$eval

    说说AngularJS中的$parse和$eval AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. ...

  8. 转:说说angularjs中的$parse和$eval

    说说AngularJS中的$parse和$eval AngularJS的初学者常常会对$parse和$eval两个内建服务感到有些困惑,今天我们就来说说AngularJS中的$parse和$eval. ...

  9. JSON.parse()和eval()的区别

    json格式非常受欢迎,而解析json的方式通常用JSON.parse()但是eval()方法也可以解析,这两者之间有什么区别呢? JSON.parse()之可以解析json格式的数据,并且会对要解析 ...

随机推荐

  1. MS Sql Server 消除重复行 保留信息完整的一条 2011-11-26 13:19(QQ空间)

    select company ,count(company) as coun into myls from mylist group by company having count(company)& ...

  2. java中的public,protected,private权限修饰

    public和private基本没问题,主要是默认的和protected之间的区别 同一包中默认的和protected一样,所以来看看不同包的情况 看下如下代码,两个类位于不同包: public cl ...

  3. Js-Html 前端系列--显示有格式的文本

    var dp = $("#dp").val(); var dpXSS = filterXss(dp); document.getElementById("descript ...

  4. 修改linux默认ssh 端口

    修改ssh的默认端口 1.编辑ssh配置文件: #vi /etc/ssh/ssh_config                  #vi /etc/ssh/sshd_config            ...

  5. 【1】Hover 效果收集

    各种 hover 效果  github repository>>  git 仓库 1. 背景图的 hover 效果 原页面>> githubSite>>

  6. FZU 2088 最长队名

    Problem 2088 最长队名  Problem Description Jack所在的班级决定组团报名参加FZU校赛.为了体现班级的团结和睦,班长决定用班级所有人的名字连起来组成一个史上最长最醒 ...

  7. jquery css hover

    <script type="text/javascript"> $(function () { $("#<%=btnSubmit.ClientID%&g ...

  8. IQueryable 和 IEnumerable

    IQueryable 和 IEnumerable 其实,对于上面的即有过虑又有排序的条件查询Linq语句,EF是读取数据库中整个Books表中的数据到内存,还是根据Linq查询语句智能的生成SQL再执 ...

  9. myBatis系列之七:事务管理

    myBatis系列之七:事务管理 如果在操作时,如果运行时错误自动进行回滚,需要以下两个配置 @Transactional()public void save(User user) { userDao ...

  10. json字符串和对象的相互转化

    json在代码中是经常用到的,在此总结一下json字符串和对象及数组之间的相互转化: 1.javascript函数方式: <1> JSON.stringify :把一个对象转换成json字 ...