请使用firefox,chrome等最新浏览器浏览本站。

angularjs指令作用域(scope)

js+jquery 阿豹 614次浏览 2个评论 扫描二维码

angularjs中每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部的Controller提供的作用域或者根作用域($rootScope)),还是创建一个新的自己的作用域,当然AngularJS为我们指令的scope参数提供了三种选择,分别是:false,true,{};默认情况下是false。

scope = false

html代码:
<div class="container" ng-controller="myCtrl">
        <p>控制器中的变量</p>
        <div class="my-info">
            我的名字是:<span ng-bind="name"></span><br/>我的年龄是:<span ng-bind="age"></span>
        </div>
        <br><br>
        <!-- 使用元素声明指令 -->
        <p>指令中的变量</p>
        <hello></hello>
</div>

js代码:
var myModule = angular.module("myModule", []);
myModule.controller('myCtrl', function($scope){
    $scope.name = "a豹";
    $scope.age = 20;
})
myModule.directive('hello', function(){
    return {
        scope: false,
        restrict: 'AE',
        template: 
        '<div>'+
        '我的名字是:<span ng-bind="name"></span><br>'+
        '我的年龄是:<span ng-bind="age"></span><br>'+
        '<input type="text" ng-model="name">'+
        '</div>',
        transclude: true,
        link: function(scope, element, attrs){
            
        }
    };
})

demo
以上代码中我们创建了hello指令, 并声明指令的scope为 false。

当我们将scope设置为false的时候,我们创建的指令和父作用域(其实是同一个作用域)共享同一个model模型,所以在指令中修改模型数据,它会反映到父作用域的模型中。
此时我们在输入框里改变名字,会发现上面的两个名字都发生了变化.

scope = true

修改上面的JS代码,将指令中的:
scope:false修改为scope:true
demo
然后我们再试着在我们的input输入框中写一些字符串,会发现,指令中的那个name发生了变化,但是指令外的那个name却没有发生变化.

当我们将scope设置为true的时候,我们就新创建了一个作用域,只不过这个作用域是继承了我们的父作用域;我觉得可以这样理解,我们新创建的作用域是一个新的作用域,只不过在初始化的时候,用了父作用域的属性和方法去填充我们这个新的作用域。它和父作用域不是同一个作用域。

scope = {}

html代码:
<div class="container" ng-controller="myCtrl">
        <p>控制器中的变量</p>
        <div class="my-info">
            我的名字是:<span ng-bind="name"></span><br/>我的年龄是:<span ng-bind="age"></span>
        </div>
        <br><br><br><br>
        <!-- 使用元素声明指令 -->
        <p>指令中的变量</p>
        <hello my-name="{{name}}" age="age"  change-my-age="changeAge()"></hello>
</div>

js代码:
var myModule = angular.module("myModule", []);
myModule.controller('myCtrl', function($scope){
    $scope.name = "a豹";
    $scope.age = 20;
    $scope.changeAge = function () {
        $scope.age = 24;
    }
})
myModule.directive('hello', function(){
    return {
        scope: {
            name: '@myName',
            age: '=age',
            changeAge: '&changeMyAge'
        },
        restrict: 'AE',
        template: "<div>" +
        "我的名字是:<span ng-bind='name'></span><br/>" +
        "我的年龄是:<span ng-bind='age'></span><br/>" +
        "在这里修改名字:<input type='text' ng-model='name'><br/>" +
        "在这里修改年龄:<input type='text' ng-model='age'><br/>" +
        "<button ng-click='changeAge()'>修改年龄</button>" +
        " </div>",
        transclude: true,
        link: function(scope, element, attrs){
            //console.log(element.children());
        }
    };
});

demo
AngularJS最强的大的地方之一就是它可以构建组建,无论放在哪里都是可以使用的;
之所以可以做到这些,不得不归功于指令的这个属性;当我们将scope设置为{}时,意味着我们创建的一个新的与父作用域隔离的新的作用域,我们使用了隔离的作用域,不代表我们不可以使用父作用域的属性和方法。
1.我们可以通过向scope的{}中传入特殊的前缀标识符(即prefix),来进行数据的绑定。
2.在创建了隔离的作用域,我们可以通过@,&,=使用指令的元素的属性,如上面的代码那样,我们可以在这个元素中<hello my-name=”{{name}}” age=”age” change-my-age=”changeAge()”></hello>,利用前缀标识符通过使用属性my-name,age,change-my-age来引用这些属性的值

@

这是一个单项绑定的前缀标识符

使用方法:

在元素中使用属性,好比这样<hello my-name=”{{name}}”></hello>,注意: 属性的名字要用-将两个单词连接,因为是数据的单项绑定所以要通过使用{{}}来绑定数据。

=

这是一个双向数据绑定前缀标识符

使用方法:

在元素中使用属性,好比这样<hello age=”age”></hello>,注意: 数据的双向绑定要通过=前缀标识符实现,所以不可以使用{{}}。

&

这是一个绑定函数方法的前缀标识符

使用方法:

在元素中使用属性,好比这样<hello change-my-age=”changeAge()”></hello>注意: 属性的名字要用-将多个个单词连接。

注意:在新创建指令的作用域对象中,使用属性的名字进行绑定时,要使用驼峰命名标准,比如下面的代码。

scope: {
            //myName就是原来元素中的my-name属性
            name: '@myName', 
            age: '=',
            changeAge: '&changeMyAge' 
        }

喜欢 (8)or分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到
(2)个小伙伴在吐槽
  1. 到此一游!
    易路营销软件2016-01-13 10:15 回复
  2. 年前再来转转!
    7488382016-02-01 10:57 回复