AngularJS Directive 隔离 Scope 数据交互

什么是隔离 Scope

AngularJS 的 directive 默认能共享父 scope 中定义的属性,例如在模版中直接使用父 scope 中的对象和属性。通常使用这种直接共享的方式可以实现一些简单的 directive 功能。当你需要创建一个可重复使用的 directive,只是偶尔需要访问或者修改父 scope 的数据,就需要使用隔离 scope。当使用隔离 scope 的时候,directive 会创建一个没有依赖父 scope 的 scope,并提供一些访问父 scope 的方式。

为什么使用隔离 Scope

当你想要写一个可重复使用的 directive,不能再依赖父 scope,这时候就需要使用隔离 scope 代替。共享 scope 可以直接共享父 scope,而隔离 scope 无法共享父scope。下图解释共享 scope 和隔离 scope 的区别:

Alt text

代码范例

<div ng-controller="myCtrl">
          <hello uname="name">
              <div>this is content</div>
          </hello>

           <hello uname="{{name}}">
              <div>this is content</div>
          </hello> 
        </div>
var module=angular.module('myApp',[]);
        module.controller('myCtrl',['$scope',function($scope) {
            $scope.name = "Feng";
        }]);

        module.directive('hello',function() {
            return {
                restrict:"EA",
                replace:false,
                transclude:true,
                scope: {
                  name:"@uname"
                },
                template:'<div>hello {{name}}</div>'
            };
        });

浏览器显示:

    scope: {
             name:"@uname"
           }

注意 默认情况下someProperty在DOM中的映射是some-property属性。如果我们想显式
指定绑定的属性名@uname,否则name:”@”默认是name:”@name”;name表示在template中的表达式属性


var module=angular.module('myApp',[]);
        module.controller('myCtrl',['$scope',function($scope) {
            $scope.name = "Feng";
        }]);

        module.directive('hello',function() {
            return {
                restrict:"EA",
                replace:false,
                transclude:true,
                scope: {
                  name:"=uname"
                },
                template:'<div>hello {{name}}</div>'
            };
        });

浏览器显示

如果html不变,javascript中,scope属性值成”@”为”=”,那么控制台会报错,而且 不能正常显示结果

directive 在使用隔离 scope 的时候,提供了三种方法同隔离之外的地方交互。这三种分别是:

  • @ 绑定一个局部 scope 属性到当前 dom 节点的属性值。结果总是一个字符串,因为 dom 属性是字符串。

    @ 方式局部属性用来访问 directive 外部环境定义的字符串值,主要是通过 directive 所在的标签属性绑定外部字符串值。这种绑定是单向的,即父 scope 的绑定变化,directive 中的 scope 的属性会同步变化,而隔离 scope 中的绑定变化,父 scope 是不知道的。

  • = 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。

    = 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。
    意思是,当你想要一个双向绑定的属性的时候,你可以使用=来引入外部属性。无论是改变父 scope 还是隔离 scope 里的属性,父 scope 和隔离 scope 都会同时更新属性值,因为它们是双向绑定的关系。

  • & 提供一种方式执行一个表达式在父 scope 的上下文中。如果没有指定 attr 名称,则属性名称为相同的本地名称。

    & 方式提供一种途经是 directive 能在父 scope 的上下文中执行一个表达式。此表达式可以是一个 function。
    比如当你写了一个 directive,当用户点击按钮时,directive 想要通知 controller,controller 无法知道 directive 中发生了什么,也许你可以通过使用 angular 中的 event 广播来做到,但是必须要在 controller 中增加一个事件监听方法。
    最好的方法就是让 directive 可以通过一个父 scope 中的 function,当 directive 中有什么动作需要更新到父 scope 中的时候,可以在父 scope 上下文中执行一段代码或者一个函数。

参考链接:https://blog.coding.net/blog/angularjs-directive-isolate-scope?type=early