我想要一个带有隔离范围的指令,并在指令中设置该范围的属性。那就是创建一些环境变量,这些变量将由其中的其他指令显示,如下所示:
HTML:
<div environment> <!-- this directive set properties to the scope it creates-->
{{ env.value }} <!-- which would be available -->
<div display1 data="env"></div> <!-- to be displayed by other directives (graphs, -->
<div display2 data="env"></div> <!-- charts...) -->
</div>
JS:
angular.module("test", [])
.directive("environment", function() {
return {
restrict: 'A',
scope: {},
link: function(scope) {
scope.env = {
value: "property set from inside the directive"
};
}
};
})
.directive("display1", function() {
return {
restrict: 'A',
require: '^environment'
scope: {
data: '='
},
link: function(scope, elt, attr, envController) {
scope.$watch('data', function(oldV, newV) {
console.log("display data");
});
}
};
})
.directive("display2", function() {
return {/* ... */};
});
但它不起作用。这是a Plunker。 如果我删除隔离,它可以正常工作。我做错了什么?这是一个跨性别问题吗?如果我在'environment'指令中使用模板似乎有效,但这不是我想要的。
感谢您的帮助。
修改:我看到同样的问题已解答here。建议的解决方案是使用控制器而不是指令。我想使用指令的原因是可以在内部指令中使用'require',这是我认为无法用ngController完成的事情。
答案 0 :(得分:0)
通过引入外部模板,我设法找到了解决问题的可行方案。 我很确定你设置它的方式在某些方面有效,但我无法确定何时。我最后一次构建了一个依赖于外部标记文件的指令而不是,我甚至都不知道。
在任何情况下,如果您愿意为指令引入单独的模板,则以下内容应该有效:
app.directive('environment', function () {
return {
restrict: 'A',
templateUrl: 'env.html',
replace: true,
scope: {},
link: function (scope, el, attrs) {
scope.env = {
value: "property set from inside the directive"
};
}
};
});
app.directive('display1', function () {
return {
restrict: 'A',
scope: {
data: '='
},
templateUrl: 'display1.html',
replace: false,
link: function(scope) {
// console.log(scope.data);
}
};
});
然后对于你的标记(这些标记不会真实地放在<script>
标签中,你很可能会有一个外部模板,但这只是从我设置的小提琴中获取的)。
<script type="text/ng-template" id="display1.html">
<span>Display1 is: {{data}}</span>
</script>
<script type="text/ng-template" id="env.html">
<div>
<h1>env.value is: {{env.value}}</h1>
<span display1 data="env.value"></span>
</div>
</script>
<div>
<div environment></div>
</div>
小提琴链接:http://jsfiddle.net/ADukg/5421/
编辑:看完之后不想要使用模板(应该先完成..),这是另一个让它运行的解决方案。不幸的是,你可以选择的唯一一个(除了一些其他的,链接来自下面),在我看来,它不是一个好看的...
app.directive('environment', function () {
return {
restrict: 'A',
template: function (element, attrs) {
return element.html();
},
scope: {},
link: function (scope, el, attrs) {
scope.env = {
value: "property set from inside the directive"
};
}
};
});
标记:
<div environment> {{env.value}} </div>
小提琴:http://jsfiddle.net/7K6KK/1/
说出你对它的看法,但确实可以解决问题。
Here's a thread off of the Angular Github Repo,概述了您的问题以及为什么不'支持'。
答案 1 :(得分:-1)
我对你的Plunker做了一个小编辑 当你在指令范围内创建变量时,其他指令可以直接或通过双向数据绑定以两种方式(在plunker中显示)访问它
<body ng-app="test">
<div environment>
{{ env.value }}
<div display1 data="env"></div>
<div display2 data="env"></div>
</div>
</body>
<input type="text" ng-model="env.value"> #added to show two-way data binding work
<div display1 info="env"></div> #changed name of attribute where variable is passed, it's then displayed inside directive template
<div display2>{{env.value}}</div> #env.value comes from environment directive not from display2
</div>
angular.module("test", [])
.directive("environment", function() {
return {
restrict: 'A',
scope: true, #changed from {} to true, each environment directive will have isolated scope
link: function(scope) {
scope.env = {
value: "property set from inside the directive"
};
}
};
})
.directive("display1", function() {
return {
restrict: 'A',
template: '<span ng-bind="info.value"></span>', #added template for directive which uses passed variable, NOTE: dot in ng-bind, if you try a two-way databinding and you don't have a dot you are doing something wrong (Misko Hevry words)
scope: {
info: '=' #set two-way data binding for variable from environment directive passed in 'info' attribute
}, #removed unnecessary watch for variable
};
})
.directive("display2", function() {
return {/* ... */};
});