假设我这样做:
sAngular.app.directive('dostuff', ['$compile', function($compile){
return {
restrict : 'C',
scope: {
someVar : '='
},
link : function(scope, element, attrs){
element.click(function(){
//do stuff
scope.someVar = 'somethingelse';
var dropdownOutput = template();
var compiledOutput = $compile(dropdownOutput)(scope);
scope.$apply();
});
}
}
}]);
如何使该指令的范围从父范围继承变量,但仍然将其作为“隔离”范围
例如来自angular docs:
=或= attr - 在本地范围属性和通过值定义的名称的父范围属性之间设置双向绑定 oftr属性。如果未指定attr名称,则为该属性 假定name与本地名称相同。给定范围的小部件定义:{ localModel:'= myAttr'},然后是widget范围属性localModel 反映父范围内parentModel的值。任何改变 parentModel将反映在localModel和任何更改中 localModel将反映在parentModel中。
但是在那种情况下,因为“localModel中的任何更改都将反映在parentModel中”,如果我在该指令的范围内修改变量,然后在这种情况下执行scope.apply(),它将相应地反映在父范围中,将使用更改
更新父模板我也尝试将“scope:true”作为参数,但更改为范围后面的范围。$ apply();也会传播到原来的范围......
有没有办法让它可以从父作用域复制作用域,并且该作用域中的变量仍然没有传播到父作用域?
答案 0 :(得分:12)
如何使该指令的范围从父范围继承变量,但仍然将其作为“隔离”范围
在这里使用“inherit”这个词有点令人困惑。隔离范围不(原型)从其父范围继承。 Angular确实在隔离范围上放置了$parent
属性,因此您可以通过这种方式访问父范围属性,但最佳做法是不使用$parent
。如果需要隔离范围,将父范围属性值传递到隔离范围的唯一方法是使用=
,@
或&
。这三个实际上都可以工作(甚至'&'可以用来通过表达式传递属性值 - for the curious)。
在您的隔离范围上(或使用scope: true
),您可以创建新属性。这些新属性不会传播回父级。因此,如果要更改传递给指令的属性值,只需将其复制到指令范围内的某个新属性即可。
以下是使用@
的示例,即“单向字符串”语法。要获取父作用域属性的(插值)值(作为字符串),请在HTML中使用{{}}:
<div class="dostuff" some-var="{{interpolateThisParentScopePropertyPlease}}">
sAngular.app.directive('dostuff', ['$compile', function($compile){
return {
restrict : 'C',
scope: { someVar : '@' },
link : function(scope, element, attrs){
element.click(function(){
scope.myLocalDirectiveProperty = scope.someVar;
scope.someOtherDirectiveProperty = 'somethingelse';
var dropdownOutput = template();
var compiledOutput = $compile(dropdownOutput)(scope);
scope.$apply();
});
}
如果要将对象传递给指令,请使用'='语法,然后使用angular.copy()
在指令中复制对象。
根据评论请求:
<div class="dostuff" some-obj="parentScopeObj">
sAngular.app.directive('dostuff', ['$compile', function($compile){
return {
restrict : 'C',
scope: { someObj : '=' },
link : function(scope, element, attrs){
element.click(function(){
scope.myLocalDirectiveObjProperty = angular.copy(scope.someObj);
...
scope.$apply();
});
}