ngModel 在 Transcluded html 中需要 $parent
ngModel needs $parent when within Transcluded html
我有一个输入字段的指令,它使用嵌入来获取包含在包含 ng-model
属性的指令元素中的元素。在阅读了无数 SO 问题和 Angular 文档以了解如何让嵌入的 html 中的 ng-model
与我指令中的 ng-model
同步之后,我终于偶然发现了一个让它工作的技巧。那就是使用 $parent
,其中 ng-model
在输入字段内。这一切都很好,但看起来 clunky/hackish。
此处显示的 Plunker:
http://plnkr.co/edit/gEje6Z2uuTs9DFPeCZfv
我试图通过在我的 link 函数中乱用嵌入函数来使它更优雅一些,如下所示:
```
var transcludedContent, transclusionScope;
transcludeFn(scope, function(clone, scope) {
//headerCtrl.$element.append(clone);
transcludedContent = clone;
transclusionScope = scope;
console.log('scope form: ', scope);
console.log('transclude form: ', clone);
});
```
此外,在此 Plunker 中显示:
http://plnkr.co/edit/11k9LiA5hyi4xydWBo3H?p=preview
有人会认为嵌入函数允许您用指令范围覆盖嵌入范围,然后 ng-model
属性将关联并绑定到指令范围,然而,这不是案件。
尽管 $parent.<ng-model>
确实有效,但它看起来很老套,并且可能导致错误,例如如果我的指令未与未定义 account
对象的父范围一起使用,就会导致错误。
有几种方法可以做到这一点。
1) 使用 =
公开 account
变量
http://plnkr.co/edit/DxsipWRj0AJe6Yi3bhse
JS:
app.directive('formControl', [function(){
return {
restrict: 'EA',
template: '<div ng-transclude></div>{{account.name}}',
scope: {
account: '='
},
transclude: true,
link: function(scope, element, attrs){
scope.account={};
console.log('SCOPE: ', scope)
}
};
}]);
HTML:
<form-control account='account'>
<label for="name">Enter Name:</label>
<input name="name" ng-model="account.name" \>
</form-control>
2) 使用transclude
函数:
这类似于 ngIf
和 ngRepeat
所做的。 ngRepeat
实际上用 $index
和类似的值装饰每个范围,就像你想用 account
.
装饰你的范围一样
http://plnkr.co/edit/cZjWqIgO23nzc0kMZA57
JS:
app.directive('formControl', ['$animate', function($animate){
return {
restrict: 'EA',
transclude: 'element',
link: function(scope, element, attrs, ctrl, transclude){
//this creates a new scope that inherits from the parent scope
//that new scope will be what you'll be working with inside your
//transcluded html
transclude(function (clone, scope) {
scope.account = {name:'foobar'};
$animate.enter(clone, null, element);
console.log('SCOPE: ', scope)
});
}
};
}]);
HTML:
<form-control>
<label for="name">Enter Name:</label>
<input name="name" ng-model="account.name" \><br>
{{account.name}}
</form-control>
我有一个输入字段的指令,它使用嵌入来获取包含在包含 ng-model
属性的指令元素中的元素。在阅读了无数 SO 问题和 Angular 文档以了解如何让嵌入的 html 中的 ng-model
与我指令中的 ng-model
同步之后,我终于偶然发现了一个让它工作的技巧。那就是使用 $parent
,其中 ng-model
在输入字段内。这一切都很好,但看起来 clunky/hackish。
此处显示的 Plunker: http://plnkr.co/edit/gEje6Z2uuTs9DFPeCZfv
我试图通过在我的 link 函数中乱用嵌入函数来使它更优雅一些,如下所示:
```
var transcludedContent, transclusionScope;
transcludeFn(scope, function(clone, scope) {
//headerCtrl.$element.append(clone);
transcludedContent = clone;
transclusionScope = scope;
console.log('scope form: ', scope);
console.log('transclude form: ', clone);
});
```
此外,在此 Plunker 中显示: http://plnkr.co/edit/11k9LiA5hyi4xydWBo3H?p=preview
有人会认为嵌入函数允许您用指令范围覆盖嵌入范围,然后 ng-model
属性将关联并绑定到指令范围,然而,这不是案件。
尽管 $parent.<ng-model>
确实有效,但它看起来很老套,并且可能导致错误,例如如果我的指令未与未定义 account
对象的父范围一起使用,就会导致错误。
有几种方法可以做到这一点。
1) 使用 =
account
变量
http://plnkr.co/edit/DxsipWRj0AJe6Yi3bhse
JS:
app.directive('formControl', [function(){
return {
restrict: 'EA',
template: '<div ng-transclude></div>{{account.name}}',
scope: {
account: '='
},
transclude: true,
link: function(scope, element, attrs){
scope.account={};
console.log('SCOPE: ', scope)
}
};
}]);
HTML:
<form-control account='account'>
<label for="name">Enter Name:</label>
<input name="name" ng-model="account.name" \>
</form-control>
2) 使用transclude
函数:
这类似于 ngIf
和 ngRepeat
所做的。 ngRepeat
实际上用 $index
和类似的值装饰每个范围,就像你想用 account
.
http://plnkr.co/edit/cZjWqIgO23nzc0kMZA57
JS:
app.directive('formControl', ['$animate', function($animate){
return {
restrict: 'EA',
transclude: 'element',
link: function(scope, element, attrs, ctrl, transclude){
//this creates a new scope that inherits from the parent scope
//that new scope will be what you'll be working with inside your
//transcluded html
transclude(function (clone, scope) {
scope.account = {name:'foobar'};
$animate.enter(clone, null, element);
console.log('SCOPE: ', scope)
});
}
};
}]);
HTML:
<form-control>
<label for="name">Enter Name:</label>
<input name="name" ng-model="account.name" \><br>
{{account.name}}
</form-control>