访问AngularJS隔离作用域的另一种方式
Alternate way to access AngularJS isolated scope
AngularJS隔离作用域是在angular指令中创建可重用组件的好方法。我非常喜欢它。有时需要访问子作用域来操作数据或调用方法。为此,angular给了我们两个选项:
(1)使用带有属性绑定的隔离作用域。像
scope: {
someObject: '='
},
(2)从DOM元素的作用域()。Angular官方文档并不保证$$childHead会提供实际的子作用域。有时有效,有时无效。
scope().$$childHead
第一个选项的问题是它给了我们只使用绑定对象/数据的选项,而不是给我们对作用域的完整访问。也许这就是Angular想要做的,但我想要完全访问隔离作用域以及它的隔离特性。为了做到这一点,我创建了以下代码(在指令链接函数中,我使用了new LinkControl(function(scope, element, attr)){…}):
function LinkController(callback){
var self = this;
self.callback = callback;
return function(scope, element, attr){
LinkController._retainScope(scope, element, attr);
self.callback.apply(this, arguments);
}
}
LinkController._scopes = {};
LinkController.get = function(scopeId) {
return LinkController._scopes[scopeId];
};
LinkController._retainScope = function(scope, element, attr){
if (typeof(attr) === 'undefined') return;
if (typeof(attr.scopeId) === 'undefined') return;
var scopeId = attr.scopeId;
LinkController._scopes[scopeId] = {
scope: scope,
element: element,
attr: attr
};
if (typeof(element) != 'undefined') {
element.on('$destroy', function(){ LinkController._releaseScope(scopeId); });
}
};
LinkController._releaseScope = function(scopeId){
delete LinkController._scopes[scopeId];
};
用法:
父控制器
app.controller('MainController', ['$scope', function($scope){
var parentData = [1, 2, 3, 4];
var anotherValue1 = LinkController.get('td01').attr.anotherValue || 'default value';
var anotherValue3 = LinkController.get('td03').attr.anotherValue || 'default value';
LinkController.get('td01').scope.data = parentData;
LinkController.get('td02').scope.showNext();
LinkController.get('td03').element.css({opacity: '.5'});
}]);