提问人:Kory 提问时间:4/30/2014 最后编辑:Kory 更新时间:4/30/2014 访问量:431
AngularJS:由其父级附加的子指令找不到其父级的控制器
AngularJS: Child directive that is appended by its parent cannot find its parent's controller
问:
我正在构建一个指令,该指令将创建一个输入列表。当您开始在第一个输入中输入信息时,一个空输入将附加到您正在处理的输入下方。
我有这个 plunkr 为第一个输入工作。麻烦的是第二个输入不会附加任何内容。
我收到此错误:错误:$compile找不到指令“child”所需的控制器“parent”!
我怀疑我需要以不同的方式添加新输入,但我不确定如何。
我已经查看了 Stack Overflow 上的其他帖子,它们对走到这一步很有帮助,但它们都没有解决与父控制器保持通信的问题。
下面是父指令:
app.directive('parent', function() {
return {
restrict: 'AE',
template: '<child name="0"></child>',
controller: function($scope, $compile, $element) {
// adds a new input within the parent
this.addChild = function(counter) {
$element.append($compile('<child name="' + counter + '"></child>')($scope));
}
}
}
});
下面是子指令:
app.directive("child", function() {
return {
restrict: "E",
scope: {},
replace: true,
require: '^parent',
controller: function($scope, $attrs) {
$scope.x = $attrs;
$scope.directiveModel = "";
$scope.$watch('directiveModel', function() {
$scope.$parent.myModel[$attrs.name] = $scope.directiveModel;
});
},
template: '<div><input type="text" name="{{x.name}}" ng-model="directiveModel"></div>',
link: function($scope, $element, attr, parentCtrl) {
var fieldCounter = 0;
var oldLength = 0;
$scope.$watch('directiveModel', function() {
// logic to determine if a new input needs to be added based on directiveModel's length
// only add inputs when directiveModel.length is going from 0 to 1
if ($scope.directiveModel.length == 1) {
if (oldLength === 0) {
fieldCounter++;
parentCtrl.addChild(fieldCounter);
}
} else if ($scope.directiveModel.length === 0) {
if (oldLength == 1 && fieldCounter > 0) {
fieldCounter--;
$element.remove();
}
}
oldLength = $scope.directiveModel.length;
}, true);
}
};
});
这是标记
<body ng-controller="MainCtrl">
<parent></parent>
<pre>{{myModel | json}}</pre>
</body>
答:
0赞
z.a.
4/30/2014
#1
观察: - 如果您继续在第一个字段上输入,然后删除所有内容,请再次写入。它成功地不断创建新的输入字段 - 我认为问题出在范围上。您的第一个子指令(父模板中的子指令)创建一个范围,该范围实际上是父指令的作用域,但所有其他指令都有自己的作用域。在 Dev Tools 的 Inspect 元素上检查它。 - 我还尝试了 emit 和 on。相同的结果。 - 因此,只有您的第一个指令是健康创建的,并且它会不断创建新的孩子。也许试着从那里开始。
0赞
Kory
4/30/2014
#2
我放弃了父子指令的整个想法。取而代之的是,我使用了一个处理所有数据操作的指令,并对存储的数据执行了 ng-repeat。
这是我的 app.js 文件
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $compile, $element) {
$scope.myModel = [
{
value: ""
}
];
});
app.directive("stackingInput", function() {
return {
restrict: "E",
scope: {
item: "=",
index: "="
},
replace: true,
template: '<div><input type="text" ng-model="item.value"></div>',
controller: function($scope, $element, attr){
var fieldCounter = 0;
var oldLength = 0;
$scope.$watch('item', function() {
if ($scope.item.value.length == 1) {
if (oldLength === 0) {
fieldCounter++;
$scope.$parent.myModel.push({value: ""});
}
}
else if ($scope.item.value.length === 0) {
if (oldLength == 1 && fieldCounter > 0) {
fieldCounter--;
$scope.$parent.myModel.splice($scope.index, 1);
}
}
oldLength = $scope.item.value.length;
}, true);
}
};
});
然后,您可以将此行添加到ng-controller元素中的标记中
<stacking-input ng-repeat="item in myModel" item="item" index="$index"></stacking-input>
评论