Javascript Angularjs 指令:隔离范围和属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14300986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 16:19:24  来源:igfitidea点击:

Angularjs directive: Isolated scope and attrs

javascriptangularjs

提问by bsr

Please see the example here

请看这里的例子

foodMeApp.directive('fmRating', function() {
  return {
    restrict: 'E',
    scope: {
      symbol: '@',
      max: '@',
      readonly: '@'
    },
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {

      attrs.max = scope.max = parseInt(scope.max || 5, 10);
...

Angular needs symbol, max, readonlyto be defined in the isolated scope object to access it from parent scope.

角需要symbolmaxreadonly以在所述分离的范围对象从父范围访问它来限定。

it is used here

在这里使用

<fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true"></fm-rating>

<fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true"></fm-rating>

So, what is the purpose of attrs? Can't one access all the attributes passed through attrs. Why can't one access value of max as attrs.maxinstead of scope.max

那么,这样做的目的是attrs什么?不能访问通过的所有属性attrs。为什么不能一个访问最大值作为attrs.max而不是scope.max

Why assign back like attrs.max = scope.max?

为什么分配回来喜欢attrs.max = scope.max

Since this app is written by Angular authors, I expect a reason.

由于这个应用程序是由 Angular 作者编写的,我希望有一个原因。

thanks.

谢谢。

回答by Mark Rajcok

what is the purpose of attrs?

attrs的目的是什么?

Attributes defined on the same element as your directive have a few purposes:

在与指令相同的元素上定义的属性有几个目的:

  1. They are the only way to pass information into a directive that uses an isolate scope. Since the directive isolate scope doesn't prototypically inherit from the parent scope, we need a way to specify what we want to pass to the isolate scope. '@', '=', and '&' in the "object hash" therefore each require an attribute to specify what data/information is being passed.
  2. They serve as an inter-directive communication mechanism. (E.g., Managing communication between independent AngularJS directives independently)
  3. They normalizethe attribute names.
  1. 它们是将信息传递到使用隔离作用域的指令的唯一方法。由于指令隔离作用域的原型并不从父作用域继承,我们需要一种方法来指定我们想要传递给隔离作用域的内容。“对象哈希”中的“@”、“=”和“&”因此每个都需要一个属性来指定正在传递的数据/信息。
  2. 它们用作指令间通信机制。(例如,独立管理独立 AngularJS 指令之间的通信
  3. 他们规范了属性名称。

Can't one access all the attributes passed through attrs?

不能访问通过 attrs 传递的所有属性吗?

Yes you can, but

是的,你可以,但是

  1. you will not have any data binding.
    '@' sets up one-way "string" databinding (parent scope → directive isolate scope) With @ the value you see/get in the directive is always a string, so don't use this if you're trying to pass an object to your directive.
    '=' sets up two-way databinding (parent scope ↔ directive isolate scope).
    Without databinding, your directive can't $watch or $observe model/data changes automatically.
  2. attribute values with {{}}s will cause you problems, since they will not be interpolated.
    Suppose we have <my-directive name="My name is {{name}}">and the parent scope has $scope.name='Mark'. Then, inside the linking function, console.log(attrs.name)results in undefined.
    If name is an isolate scope property defined with '@', then attrs.$observe('name', function(val) { console.log(val) })results in My name is Mark. (Note that inside the linking function, $observe() must be used to get the interpolated value.)
  1. 你不会有任何数据绑定。
    '@' 设置单向“字符串”数据绑定(父作用域→指令隔离作用域)使用@,您在指令中看到/获得的值始终是一个字符串,因此如果您尝试传递一个字符串,请不要使用它反对你的指令。
    '=' 设置双向数据绑定(父作用域 ↔ 指令隔离作用域)。
    如果没有数据绑定,您的指令将无法自动 $watch 或 $observe 模型/数据更改。
  2. 带有{{}}s 的属性值会给您带来问题,因为它们不会被插值。
    假设我们有<my-directive name="My name is {{name}}">并且父作用域有$scope.name='Mark'。然后,在链接函数内部,console.log(attrs.name)结果为undefined
    如果 name 是使用“@”定义的隔离范围属性,则attrs.$observe('name', function(val) { console.log(val) })结果为My name is Mark. (请注意,在链接函数内部,必须使用 $observe() 来获取插值。)

Why can't one access value of max as attrs.max instead of scope.max

为什么不能将 max 的一个访问值作为 attrs.max 而不是 scope.max

answered above

以上回答

Why assign back like attrs.max = scope.max ?

为什么像 attrs.max = scope.max 那样分配回来?

The only reason I can think of for doing this is in case some other directive needs to see this attribute/value (i.e., inter-directive communication). However, the other directive would need to run after this directive for this to work (which can be controlled somewhat with the prioritydirective setting).

我能想到这样做的唯一原因是以防其他指令需要查看此属性/值(即指令间通信)。但是,另一个指令需要在此指令之后运行才能使其工作(可以通过priority指令设置进行某种程度的控制)。

Summary: in a directive with an isolate scope, normally you don't want to use attrs. (I suppose it could be a way to send initialization data/values into a directive -- i.e., if you don't need databinding for these values and you don't need interpolation.)

总结:在具有隔离作用域的指令中,通常您不想使用attrs. (我想这可能是一种将初始化数据/值发送到指令中的方法——即,如果您不需要这些值的数据绑定并且不需要插值。)

回答by Ivo

Using attrs you are able to access the attributes defined in your html tag like

使用 attrs,您可以访问 html 标签中定义的属性,例如

<fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true">

So in this case you will have access to the symboland readonlyattributes. Every attribute you define in your custom directive will be available to the attrsvariable.

因此,在这种情况下,您将可以访问符号只读属性。您在自定义指令中定义的每个属性都可用于attrs变量。

The block:

块:

attrs.max = scope.max = parseInt(scope.max || 5, 10);

Will parse and assignthe current scope.maxvalue or 5, if non existent, to the scope.max and attrs.max. This way, after the assignment you can read from attrs.max. Before that the attrs.max property in undefined.

解析并将当前scope.max值或5分配给scope.max 和 attrs.max。这样,在分配之后您可以从 attrs.max 读取。在此之前 attrs.max 属性未定义。

Inspecting the fmRating.js source i don't know why/where/when this piece of code is being used.

检查 fmRating.js 源代码我不知道为什么/在哪里/何时使用这段代码。