我对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');
};
}
}
});
这里发生了什么?
答案 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') });
}
}
});