让我们假设我有一个类似的AngularJS指令:
app.directive('psDIR', [
function() {
return {
template: "<div style='padding: 5px; border: 1px solid red; margin-bottom: 10px;'><p>This is a direcive:</p> <textarea rows='5' cols='50' ng-model='md'></textarea></div>",
restrict: 'AEC',
scope: {}
}
}
]);
我在一个页面上使用此指令的次数。如何获取ng-model="md"
中MainCtrl
的每个指令实例/范围的值(即我想将此值保存在add()
中):
app.controller('MainCtrl', ['$scope',
function($scope) {
console.log("init");
$scope.add = function() {
console.log($scope);
}
}
]);
Plunker演示:http://embed.plnkr.co/Q5bw6CBxPYeNe7q6vPsk/preview
任何建议都非常感谢。
答案 0 :(得分:3)
由于您正在创建隔离范围,否则您也无法从父范围访问子范围。
将模型作为参数传递出来的方法,如
<div class="psDIR" model='field2'></div>
<div class="psDIR" model='field1'></div>
然后在指令中用属性绑定更新它们。请参阅update plunkr
答案 1 :(得分:2)
可能的解决方案是使用require
:
app.directive('psDIR', [
function() {
return {
...,
require: "ngController",
link: function(scope, elem, attrs, ngCtrl) {
ngCtrl.hook(scope);
}
}
}
]);
对控制器进行必要的更改:
app.controller('MainCtrl', ['$scope',
function($scope) {
console.log("init");
$scope.add = function() {
var i;
for( i=0; i < psDirs.length; i++ ) {
console.log(i + " -> " + psDirs[i].md);
}
}
var psDirs = [];
this.hook = function(scope) {
psDirs.push(scope);
};
}
]);
在此处试试:http://plnkr.co/edit/zCZ1TOm3aK8V4piCAY6u?p=preview
如果您决定使用此解决方案,我建议在专门的包装器指令中实现“包装器”控制器,以避免在层次结构中的某些其他元素中设置ng-controller
的情况。在这种情况下,只需require: "wrapperDirective"
。
编辑:包装器指令案例的HTML看起来像:
<div wrapper-directive>
<div class="psDIR"></div>
<div class="psDIR"></div>
<button ng-click="add()">Add</button>
</div>
该指令本身使用前一个ng-controller
:
app.directive('wrapperDirective', function() {
return {
restrict: "A",
// YOU MAY WANT ISOLATED SCOPE, JUST ADD scope: {},
controller: ["$scope", function($scope) {
// SAME CODE AS BEFORE
console.log("init");
$scope.add = function() {
var i;
for( i=0; i < psDirs.length; i++ ) {
console.log(i + " -> " + psDirs[i].md);
}
}
var psDirs = [];
this.hook = function(scope) {
psDirs.push(scope);
};
}]
};
});
当然更改require
配置:
app.directive('psDIR', [
...
require: "^wrapperDirective",
link: function(scope, elem, attrs, wrapperDirectiveCtrl) {
wrapperDirectiveCtrl.hook(scope);
}
答案 2 :(得分:2)
当您想要在范围(即指令和其他控制器)之间进行通信时,通常正确的做法是使用服务。
您可以在此处查看一个简单的plunker:http://plnkr.co/edit/8Al31Bq9BfoazUCpqhWy?p=preview
psDirs
服务保留了指令的注册表:
app.service('psDirs', function() {
var psDirs = {
dirs: [],
register: function (dir) {
psDirs.dirs.push(dir);
}
};
return psDirs;
});
指令会自行注册并在更改时更新值:
link: function (scope, elm, attr) {
var dir = { val: "" };
psDirs.register(dir);
scope.$watch('md', function (n, o) {
if (n !== o) {
dir.val = n;
}
});
}
然后您的控制器可以注入psDirs服务并根据需要访问指令注册表。这可以防止脆弱的范围关系,并允许指令注册表服务在其他地方,应用程序的多个控制器和部分中使用。