指令中的scope

一般而言,指令配置如下:

//headBar.js
angular.module('app')
.directive('appHeadBar', function() {
  return {
    restrict: 'A',
    replace: true,
    templateUrl: 'view/template/headBar.html',
    scope: {
      text: '@',
    },
    link: function(scope, element, attr) {
      scope.back = function() {
        window.history.back(); // 调用浏览器的api实现后退功能
      }
    }
  }
})
// 指令对应的模板页面headBar.html
<div class="head ta-c p-r">
  <span class="p-a c-w back-btn" ng-click="back();">&lt;</span> // 绑定点击函数,在指令link函数中实现
  <span class="c-w" ng-bind="text"></span>
</div>

除了这些之外,还有transcludecompile等等属性。

指令中重要的是scope属性,默认是false,表示与父作用域是同一个作用域。如果设置为true,表示会从父作用域继承并创建一个新的作用域对象。

如果一个元素上有多个指令使用了隔离作用域,其中只有一个可以生效,所以最好不好这么做。只有指令模板的根元素可以获得一个新的作用域。

scope还有一个值是{}。这表示一个隔离作用域。这样,指令模板就无法访问外部作用域了。不过使用无数据的隔离作用域并不常见。AngularJS提供了三种方法能够将指令内部的隔离作用域同指令外部的作用域进行数据绑定。

  • @ (or @attr) 把当前属性作为字符串传递。
  • = (or =attr) 绑定当前属性,它是一个来自指令父作用域的属性。
  • & (or &attr) 传递一个来自父作用域的函数,稍后调用。

这里会涉及到三个部分。
1、该指令所在的HTML部分(对应父作用域)
2、该指令的定义部分
3、该指令对应的templateUrl/template部分

对@的举例
// 1 父控制器中的html
<div app-head-bar text="公司职位"></div>

// 2
angular.module('app')
.directive('appHeadBar', function() {
  return {
    restrict: 'A',
    replace: true,
    templateUrl: 'view/template/headBar.html',
    scope: {
      text: '@',
    },
  }
})

// 3
<span class="c-w" ng-bind="text"></span>

对以上的解析是,指令的templaterUrl中,即上述的第3部分,bg-bind="text"。我们在指令定义部分(第2部分)可以看到text使用的是@符号。根据@符号的规则,到指令所在的HTML部分(第1部分)查找这个属性,对应的值是“公司职位”,所以第3部分span中的值就是“公司职位”了。

对=的举例

// 1 父作用域对应的是控制器companyCtrl
<div app-position-class com="company"></div>

angular.module('app')
.controller('companyCtrl', ['$http', '$state', '$scope', function($http, $state, $scope) {
  $http.get('data/company.json?id=' + $state.params.id)
  .then(function(res) {
    $scope.company = res.data; // company.positionClass是一个json数据,在指令对应的模板中引用了
  })
}])

// 2
angular.module('app')
.directive('appPositionClass', [function() {
  return {
    restrict: 'A',
    replace: true,
    templateUrl: 'view/template/positionClass.html',
    scope: {
      com: '=' //可以看到,对应的是父作用域中的company属性
    },
  }
}])

// 3
<button class="{{$index===isActive ? 'active' : ''}}" ng-repeat="cls in com.positionClass" ng-bind="cls.name"></button> 

对以上的解析是,指令的templaterUrl中,即上述的第3部分,ng-repeat中使用了com.positionClasscom属性。在指令中查找这个属性,使用的是=号。再到指令所在的HTML部分(第1部分)可以看到com="company"。根据=的规则,这个company应该是父作用域中的一个属性,可以看到,这个属性($scope.company)依赖于一个异步请求。

对&的举例

// 1 父作用域对应的是控制器searchCtrl
<div app-tab tab-click="tClick(id, name)"></div>

angular.module('app')
.controller('searchCtrl', ['dict', '$http', '$scope', function(dict, $http, $scope) {
  var tabId = '';
  $scope.tClick = function(id, name) { // tabClick

  }
}])

// 2
angular.module('app')
.directive('appTab', [function() {
  return {
    restrict: 'A',
    replace: true,
    scope: {
      list: '=',
      tabClick: '&'
    },
    templateUrl: 'view/template/tab.html',
    link: function(scope) {
      scope.click = function(tab) {
        scope.selectId = tab.id;
        scope.tabClick(tab);
      }
    }
  }
}])

// 3
<ul class="tab">
  <li class="d-ib ta-c" ng-repeat="item in list" ng-bind="item.name" ng-click="click(item)"></li> 
</ul>

对以上的解析是,指令的templaterUrl中,即上述的第3部分,点击li元素会调用指令中link中的click事件。从而调用指令的tabClick函数,在指令中查找这个属性,使用的是&符号。再到指令所在的HTML部分(第1部分)可以看到tab-click="tClick(id, name)"。根据&规则,tabClick对应的父作用域的tClick函数,从而调用父作用域的这个函数。

关于此,要注意的一点是在指令的定义中调用scope.tabClick(tab)参数是一个对象,但是在指定的html代码部分参数是这个对象的某些属性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值