在指令中使用scope: { ... }
会引入隔离范围,该范围不会从其父范围原型继承。但我总是将它用于另一个原因:使用双向数据绑定声明HTML属性的便捷方式:
scope: {
attr1: '=',
attr2: '?='
}
要获得非隔离范围,必须使用scope: true
,它不提供声明此类属性的机会。我现在发现自己需要一个非隔离范围的指令,但具有双向绑定。实现这一目标的最佳途径是什么?
示例:我的用例是这样的,在outer-directive
:
<div ng-repeat="e in element">
<inner-directive two-way-attr="e.value"></inner-directive>
</div>
但inner-directive
与outer-directive
位于同一模块中。它不需要用隔离范围封装。事实上,我需要将$scope
继承用于其他目的,因此隔离范围不是一个选项。只是使用HTML属性来建立这种双向通信非常方便。
答案 0 :(得分:14)
像素比特的答案帮助我解决了这个大问题,但作为我原始问题的直接答案,它似乎过于复杂。在研究之后,解决方案非常简单。
采用如下隔离范围的指令:
scope: { model: '=myModel' },
link: function(scope, element, attr) {
//...
}
以下是等效的,但范围不是孤立的:
scope: true,
link: function(scope, element, attr) {
scope.model = scope.$parent.$eval(attr.myModel);
//...
}
请参阅此处的工作示例:http://jsfiddle.net/mhelvens/SZ55R/1/
答案 1 :(得分:7)
相同指令中可以同时具有非隔离范围和隔离范围。您可能希望这样做,例如,如果您混合使用两个非隔离模板(意味着它们不应通过范围继承寻找绑定),以及隔离模板(它们应仅在其自己的范围内查找绑定)和它们都在同一指令中定义。
为了设置隔离范围和非隔离范围,您可以执行以下操作:
scope=true
在链接函数中,根据scope参数编译和链接模板。执行此操作时,将针对非隔离范围评估绑定(意味着它通过原型范围继承解析绑定)。
link: function(scope, element, attr) {
// this template should look for 'model' using scope inheritance
var template2 = angular.element('<div> Prototypical Scope: {{ model }}</div>');
// add the template to the DOM
element.append(template2);
// compile and link the template against the prototypical scope
$compile(template2)(scope);
}
原型范围继承的优点是您不必明确地将绑定导入您的指令&#39;目前的范围。只要它在当前作用域中定义,或者在继承链上方的任何作用域(一直到根作用域)中定义,角度运行时将能够解析它。
在相同的链接功能中,使用scope.$new(true)
定义隔离范围。您可以通过将模型导入隔离范围来建立模型的双向绑定 - isolatedScope.model = scope.$eval(attr.model)
:
link: function(scope, element, attr) {
// this template should look for 'model' in the current isolated scope only
var template = angular.element('<div>Isolate Scope: {{model}}</div>');
// create an isolate scope
var isolatedScope = scope.$new(true);
// import the model from the parent scope into your isolated scope. This establishes the two-way binding.
isolatedScope.model = scope.$eval(attr.model);
// add the template to the DOM
element.append(template);
// compile and link the template against the isolate scope
$compile(template)(isolatedScope);
}
隔离范围的优点是任何存在的绑定(即在范围内)都是您明确导入的绑定。将此与非隔离范围进行对比 - 其中绑定不需要在当前范围内明确定义 - 它可以从链上方的任何范围继承。
答案 2 :(得分:6)
我写了这个。你这样使用它:
twowaybinder.attach($scope, $attrs.isDeactivated, 'isDeactivated');
.factory('twowaybinder', function ($parse) {
function twoWayBind($scope, remote, local){
var remoteSetter = $parse(remote).assign;
var localSetter = $parse(local).assign;
$scope.$parent.$watch(remote, function (value) {
localSetter($scope, value);
});
$scope.$watch(local, function (value) {
remoteSetter($scope, value);
});
}
return {
attach : twoWayBind
};
});
它将从范围值给出真正的双向绑定。注意我不认为$ scope。$ parent是必要的,因为在继承或无范围的情况下,任何表达式都应解析当前范围。您只需要在隔离范围内调用$ parent,在这种情况下您不会使用它,您将使用隔离范围配置。
答案 3 :(得分:-3)
您可以使用两个指令 如果gg是一个对象,那么“=”指向一个记忆位置!
angular.module('mymodule', []).directive('a', function($parse, $modal) {
return {
restrict : 'A',
scope : {
gg : "="
},
require : "b",
link : function(scope, element, attrs, bCtrl) {
scope.$watch('gg',function(gg){
bCtrl.setset(scope.gg);
}
}
}
});
angular.module('mymodule').directive('b', function($parse, $modal) {
return {
restrict : 'A',
/*
* scope : { showWarn : "=" },
*/
controller : function($scope) {
$scope.bb = {};
this.setset = function(nn) {
$scope.bb=nn;
};
}
});