Ema*_*mad 74 angularjs angularjs-directive
我想将我的表单字段封装在一个指令中,所以我可以简单地这样做:
<div ng-form='myForm'>
<my-input name='Email' type='email' label='Email Address' placeholder="Enter email" ng-model='model.email' required='false'></my-input>
</div>
Run Code Online (Sandbox Code Playgroud)
如何访问myForm我的指令,以便进行验证检查,例如myForm.Email.$valid?
Mar*_*cok 151
要在指令中访问FormController:
require: '^form',
Run Code Online (Sandbox Code Playgroud)
然后它将作为链接函数的第4个参数:
link: function(scope, element, attrs, formCtrl) {
console.log(formCtrl);
}
Run Code Online (Sandbox Code Playgroud)
您可能只需要访问NgModelController:
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
console.log(ngModelCtrl);
}
Run Code Online (Sandbox Code Playgroud)
如果您需要访问两者:
require: ['^form','ngModel'],
link: function(scope, element, attrs, ctrls) {
console.log(ctrls);
}
Run Code Online (Sandbox Code Playgroud)
tan*_*y_k 32
这是一个完整的例子(使用Bootstrap 3.1设计)
它包含一个包含多个输入(名称,电子邮件,年龄和国家/地区)的表单.姓名,电子邮件和年龄是指令.国家是"常规"投入.
当用户未输入正确的值时,每个输入都会显示一条帮助消息.
表单包含一个保存按钮,如果表单至少包含一个错误,该按钮将被禁用.
<!-- index.html -->
<body ng-controller="AppCtrl">
<script>
var app = angular.module('app', []);
app.controller('AppCtrl', function($scope) {
$scope.person = {};
});
</script>
<script src="inputName.js"></script>
<script src="InputNameCtrl.js"></script>
<!-- ... -->
<form name="myForm" class="form-horizontal" novalidate>
<div class="form-group">
<input-name ng-model='person.name' required></input-name>
</div>
<!-- ... -->
<div class="form-group">
<div class="col-sm-offset-2 col-sm-4">
<button class="btn btn-primary" ng-disabled="myForm.$invalid">
<span class="glyphicon glyphicon-cloud-upload"></span> Save
</button>
</div>
</div>
</form>
Person: <pre>{{person | json}}</pre>
Form $error: <pre>{{myForm.$error | json}}</pre>
<p>Is the form valid?: {{myForm.$valid}}</p>
<p>Is name valid?: {{myForm.name.$valid}}</p>
</body>
// inputName.js
app.directive('inputName', function() {
return {
restrict: 'E',
templateUrl: 'input-name.html',
replace: false,
controller: 'InputNameCtrl',
require: ['^form', 'ngModel'],
// See Isolating the Scope of a Directive http://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive
scope: {},
link: function(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
var ngModel = ctrls[1];
if (attrs.required !== undefined) {
// If attribute required exists
// ng-required takes a boolean
scope.required = true;
}
scope.$watch('name', function() {
ngModel.$setViewValue(scope.name);
});
}
};
});
// inputNameCtrl
app.controller('InputNameCtrl', ['$scope', function($scope) {
}]);
Run Code Online (Sandbox Code Playgroud)
Ove*_*ous 17
编辑2:我会留下我的答案,因为它可能有其他原因,但Mark Rajcok的另一个答案是我原本想做的,但未能开始工作.显然,这里的父控制器将是form,而不是ngForm.
您可以使用指令中的属性传递它,尽管这会变得相当冗长.
这是一个有效的,简化的jsFiddle.
HTML:
<div ng-form="myForm">
<my-input form="myForm"></my-input>
</div>
Run Code Online (Sandbox Code Playgroud)
指令的基本部分:
app.directive('myInput', function() {
return {
scope: {
form: '='
},
link: function(scope, element, attrs) {
console.log(scope.form);
}
};
});
Run Code Online (Sandbox Code Playgroud)
我们已经要求Angular将form属性中指定的范围值绑定到我们的隔离范围,方法是使用'='.
这样做可以将实际形式与输入指令分离.
注意:我尝试使用require: "^ngForm",但是ngForm指令没有定义控制器,也不能以这种方式使用(这太糟糕了).
所有这一切,我认为这是一个非常冗长和混乱的方式来处理这个问题.您可能最好将新指令添加到表单元素,并用于require访问该项目.我会看看能不能把东西放在一起.
好的,这是我可以找到的最好的父指令,我会在一秒钟内解释更多:
HTML:
<div ng-app="myApp">
<div ng-form="theForm">
<my-form form="theForm">
<my-input></my-input>
</my-form>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
JS(部分):
app.directive('myForm', function() {
return {
restrict: 'E',
scope: {
form: '='
},
controller: ['$scope', function($scope) {
this.getForm = function() {
return $scope.form;
}
}]
}
});
app.directive('myInput', function() {
return {
require: '^myForm',
link: function(scope, element, attrs, myForm) {
console.log(myForm.getForm());
}
};
});
Run Code Online (Sandbox Code Playgroud)
这将表单存储在父指令scope(myForm)中,并允许子指令通过要求父表单(require: '^myForm')和访问链接函数(myForm.getForm())中的指令控制器来访问它.
优点:
劣势:
我试图使用表单元素上的属性使其工作.如果这样做,你只需要将指令添加到同一个元素中ngForm.
但是,我在范围内得到了一些奇怪的行为,其中myFormName变量将在其中可见$scope,但是undefined当我尝试访问它时.那个让我困惑的人.
从AngularJS 1.5.0开始,有更清晰的解决方案(与link直接使用该功能相反).如果要访问FormController子组件的指令控制器中的表单,可以简单地require在指令上打一个属性,如下所示:
return {
restrict : 'EA',
require : {
form : '^'
},
controller : MyDirectiveController,
controllerAs : 'vm',
bindToController : true,
...
};
Run Code Online (Sandbox Code Playgroud)
接下来,您将能够像在任何其他范围变量中一样在模板或指令控制器中访问它,例如:
function MyDirectiveController() {
var vm = this;
console.log('Is the form valid? - %s', vm.form.$valid);
}
Run Code Online (Sandbox Code Playgroud)
请注意,为此,您还需要bindToController: true在指令上设置属性.查看文档的$compile和这个问题的更多信息.
文件中的相关部分:
要求
需要另一个指令并将其控制器作为链接函数的第四个参数注入.require属性可以是字符串,数组或对象:
如果require属性是一个对象并且
bindToController是真实的,那么使用require属性的键将所需的控制器绑定到控制器.如果所需控制器的名称与本地名称(密钥)相同,则可以省略该名称.例如,{parentDir: '^parentDir'}相当于{parentDir: '^'}.
| 归档时间: |
|
| 查看次数: |
59597 次 |
| 最近记录: |