我已经仔细阅读了AngularJS关于这个主题的文档,然后摆弄了一个指令。这是小提琴。

以下是一些相关片段:

来自HTML: <窗格bi-title = "标题" title =“{{标题}}>{{文本}}> < /窗格 从窗格指令: scope: {biTitle: '=', title: '@', bar: '='},

有几件事我不明白:

为什么我必须使用“{{title}}”与“@”和“title”与“=”? 我也可以直接访问父范围,而不装饰我的元素与属性? 文档说:“通常情况下,通过表达式将数据从孤立的作用域传递到父作用域是可取的”,但这似乎也适用于双向绑定。为什么表达式路由会更好呢?

我发现另一个小提琴,显示表达式解决方案太:http://jsfiddle.net/maxisam/QrCXh/


当前回答

@将局部/指令作用域属性绑定到DOM属性的评估值。 =将局部/指令作用域属性绑定到父作用域属性。 & binding用于将方法传递到指令的作用域,以便在指令中调用它。

@属性字符串绑定 =双向模型绑定 &回调方法绑定

其他回答

=表示双向绑定,即父作用域的变量引用。这意味着,当你在指令中改变变量时,它也会在父作用域中被改变。

@意味着变量将被复制(克隆)到指令中。

据我所知,<pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>也应该工作。Bi-title将接收父范围变量值,该值可以在指令中更改。

如果你需要改变父作用域中的几个变量,你可以在指令内执行父作用域中的函数(或者通过服务传递数据)。

如果您想通过一个现场示例了解更多这是如何工作的。http://jsfiddle.net/juanmendez/k6chmnch/

var app = angular.module('app', []);
app.controller("myController", function ($scope) {
    $scope.title = "binding";
});
app.directive("jmFind", function () {
    return {
        replace: true,
        restrict: 'C',
        transclude: true,
        scope: {
            title1: "=",
            title2: "@"
        },
        template: "<div><p>{{title1}} {{title2}}</p></div>"
    };
});

=方法是双向绑定,它允许你在指令中进行实时更改。当有人在指令外更改变量时,你将在指令内拥有更改的数据,但@ way不是双向绑定。它像文本一样工作。你绑定一次,你就只有它的值。

为了更清楚地理解它,你可以使用这篇很棒的文章:

AngularJS指令作用域'@'和'='

我创建了一个小的HTML文件,里面有Angular代码来演示它们之间的区别:

<!DOCTYPE html>
<html>
  <head>
    <title>Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  </head>
  <body ng-app="myApp">
    <div ng-controller="myCtrl as VM">
      <a my-dir
        attr1="VM.sayHi('Juan')" <!-- scope: "=" -->
        attr2="VM.sayHi('Juan')" <!-- scope: "@" -->
        attr3="VM.sayHi('Juan')" <!-- scope: "&" -->
      ></a>
    </div>
    <script>
    angular.module("myApp", [])
    .controller("myCtrl", [function(){
      var vm = this;
      vm.sayHi = function(name){
        return ("Hey there, " + name);
      }
    }])
    .directive("myDir", [function(){
      return {
        scope: {
          attr1: "=",
          attr2: "@",
          attr3: "&"
        },
        link: function(scope){
          console.log(scope.attr1);   // =, logs "Hey there, Juan"
          console.log(scope.attr2);   // @, logs "VM.sayHi('Juan')"
          console.log(scope.attr3);   // &, logs "function (a){return h(c,a)}"
          console.log(scope.attr3()); // &, logs "Hey there, Juan"
        }
      }
    }]);
    </script>
  </body>
</html>

为什么我必须使用“{{title}}”与“@”和“title”与“=”?

@ binds a local/directive scope property to the evaluated value of the DOM attribute. If you use title=title1 or title="title1", the value of DOM attribute "title" is simply the string title1. If you use title="{{title}}", the value of the DOM attribute "title" is the interpolated value of {{title}}, hence the string will be whatever parent scope property "title" is currently set to. Since attribute values are always strings, you will always end up with a string value for this property in the directive's scope when using @.

=将局部/指令作用域属性绑定到父作用域属性。因此,使用=,您使用父模型/作用域属性名作为DOM属性的值。{{}}不能与=一起使用。

使用@,你可以这样做title="{{title}},然后some"——{{title}}被插入,然后字符串"and them some"与它连接。最后一个串接的字符串是local/directive scope属性得到的。(你不能用=,只能用@。)

对于@,您将需要使用attr。$observe('title',函数(值){…})如果你需要在你的link(ing)函数中使用该值。例如,如果范围。Title == "…")不会像你期望的那样工作。注意,这意味着您只能异步访问该属性。 如果只使用模板中的值,则不需要使用$observe()。例如,模板:'<div>{{title}}</div>'。

使用=,您不需要使用$observe。

我也可以直接访问父范围,而不装饰我的元素与属性?

是的,但前提是你不使用孤立的作用域。从指令中删除这一行

范围:{…}

然后你的指令不会创建一个新的作用域。它将使用父作用域。然后,您可以直接访问所有父范围属性。

文档中说:“通常情况下,通过表达式将数据从孤立的作用域传递到父作用域是可取的”,但这似乎也适用于双向绑定。为什么表达式路由会更好呢?

是的,双向绑定允许本地/指令作用域和父作用域共享数据。“表达式绑定”允许指令调用由DOM属性定义的表达式(或函数)——您还可以将数据作为参数传递给表达式或函数。因此,如果您不需要与父对象共享数据——您只想调用父对象作用域中定义的函数——您可以使用&语法。

另请参阅

Lukas的孤立范围博客文章(涵盖@,=,&) Dnc253对@和=的解释 我关于作用域的博客般的回答——指令部分(在底部,就在摘要部分之前)有一个孤立作用域和它的父作用域的图片——指令作用域使用@表示一个属性,使用=表示另一个属性 在angularJS中& vs @和=的区别是什么