Angular 1.2.16,隔离范围,父函数和ng-click

时间:2014-04-29 04:03:23

标签: javascript angularjs angularjs-directive angularjs-scope

我对Angular的一个相当简单的问题感到困惑(我认为这很简单)。有时Angular让我感到愚蠢,因为我做错了一件事是不可能的。

拿这个plnkr http://plnkr.co/edit/BmM9C5zjDAIfGTVzkU29?p=preview

HTML:

<body ng-app="app">
  <div ng-controller="ASDF">
    <div fb-login="doh" ng-click="exec()">CLICKY (should execute parent scope function but doesnt)</div>
  </div>
</body>

使用Javascript:

angular.module('app', [])
.controller('ASDF', function($scope){
   $scope.doh = function(d){
      alert(d);
   }
})
.directive('fbLogin', function(){
   return {
     restrict: 'A',
     replace: false,
     scope: {
       done: '&fbLogin'
     },
     link: function(scope){
       scope.exec = function(){
         scope.done()('asdf');
       };
     }
   }
});

这里发生了什么?

2 个答案:

答案 0 :(得分:2)

1.2版本中的隔离范围是完全隔离的(参见https://github.com/angular/angular.js/commit/909cabd36d779598763cc358979ecd85bb40d4d7

  

修复($ compile):使隔离范围真正隔离

     

修复了隔离范围泄漏到其他地方的问题   关于同一元素的指令。

     

隔离范围现在仅适用于isolate指令   请求它及其模板。

     

非隔离指令不应该获得隔离的隔离范围   相同元素的指令,而不是他们将收到原始   scope(新创建的隔离范围的父范围)。

     

与Tobias配对。

     

突然变更:没有隔离范围的指令无法获得   将范围与同一元素上的isolate指令隔离。如果你的   代码取决于此行为(非隔离指令需要访问   从隔离范围内的状态),将isolate指令更改为   使用范围locals明确传递这些。

     

//

之前      

.directive('ngIsolate',function(){return {       范围: {},       模板:'{{value}}'}; });

     

//

之后      

.directive('ngIsolate',function(){return {       范围:{value:'= ngModel'},       模板:'{{value}}}; });

然后现在唯一可行的方法是通过模板/ templateUrl(在这种情况下使用transclude,所以我不需要重新创建它):

angular.module('app', [])
.controller('ASDF', function($scope){
   $scope.doh = function(d){
     alert(d);
  }
})
.directive('fbLogin', function(){
   return {
     restrict: 'A',
     replace: false,
     scope: {
       done: '&fbLogin'
     },
     transclude: true,
     template: '<div ng-transclude ng-click="exec()"></div>',
     link: function(scope){         
       scope.exec = function(){
         scope.done()('asdf');
       };
     }
   }
});

答案 1 :(得分:1)

因为ng-click只能访问父作用域,所以它试图在ASDF控制器的作用域上执行exec。

我相信这会给你你想要的行为:

HTML:

<body ng-app="app">
  <div ng-controller="ASDF">
    <div fb-login="doh">CLICKY (should execute parent scope function but doesnt)</div>
  </div>
</body>

使用Javascript:

angular.module('app', [])
.controller('ASDF', function($scope){
   $scope.doh = function(d){
      alert(d);
   }
})
.directive('fbLogin', function(){
   return {
     restrict: 'A',
     replace: false,
     scope: {
       done: '&fbLogin'
     },
     link: function(scope, element){
       element.on("click", function () { scope.done()('asdf') });
     }
   }
});