hgc*_*rpd 9 forms angularjs angularjs-directive
我最初在这里提出了这个问题,但我认为我已经领先于自己并使其变得比实际情况更复杂,所以我在这里重新提出一些更清晰的措辞.
如何使用指令和可重用参数创建可重用的窗体小部件?像这样:
<form>
<special-input label-text="A Special Input" bind-to="data.special"></special-input>
<special-input label-text="Specialer" bind-to="data.moreSpecial"></special-input>
</form>
Run Code Online (Sandbox Code Playgroud)
指令模板似乎不允许在ng-model上进行插值.
此外,您是否可以模块化和参数化表单行为,以便您可以进行标准的POST操作,例如?
我根据我的实验回答了下面的问题,但是我暂时不接受它,因为我对Angular很新,并希望听到其他人的意见.
hgc*_*rpd 15
Angular开箱即用,带有一个改进的标签,在此处记录. 基本上,它围绕表单及其中的所有标记以控制器的形式创建范围.所以你这样做:
<body ng-app="TestApp">
<form ng-controller="FormCtrl" name="testForm">
<input name="firstInput" ng-model="data.first">
<input name="secondInput" ng-model="data.second">
<button ng-click="submit()">Submit</button>
</form>
</body>
Run Code Online (Sandbox Code Playgroud)
JS:
var app = angular.app('TestApp', []);
app.controller('FormCtrl', function($scope) {
$scope.submit = function() {
// Form submit logic here
console.log("Submitting the form");
console.log($scope);
}
})
Run Code Online (Sandbox Code Playgroud)
这会为表单创建一个范围,因为表单标记包含ng-controller标记.在范围内,testForm是表单testForm.firstInput的javascript对象,并且是第一个输入的javascript对象.看起来这些对象也有一些可用的验证功能,请参阅此处的文档.
表单上的数据将作为FormCtrl范围内的对象数据提供,其中键为"first"和"second",您可以在控制器中定义处理该方法的方法.
您也可以使用相同的FormCtrl放置多个表单,似乎Angular将为每个表单创建新实例,因此您不必担心表单会污染彼此的数据.
现在让我们假设我们有一些在指令中实现的复杂输入或小部件.此示例使用两个选择框来显示州中的所有城市.您必须首先选择一个州,然后它将查询该州的城市并填充第二个选择框.
app.directive('citySelect', function() {
return {
replace: true,
template: '<div><select ng-change="getCities()" ng-options="s.name for s in states"></select>' +
'<select ng-model="data.selectedCity" ng-options="c.name for c in cities"></select>',
controller: function($scope) {
// Omitting the logic for getCities(), but it'd go here
}
};
})
Run Code Online (Sandbox Code Playgroud)
然后你可以将它粘贴到表单标签中,它会起作用.因为该指令没有定义范围,所以它只会附加到FormCtrl的范围.
<body ng-app="TestApp">
<form ng-controller="FormCtrl" name="testForm">
<input name="firstInput" ng-model="data.first">
<input name="secondInput" ng-model="data.second">
<div city-select></div>
<button ng-click="submit()">Submit</button>
</form>
</body>
Run Code Online (Sandbox Code Playgroud)
编辑: 显然这确实有效:
scope: {someParameter: "="},
template: '<div><select ng-model="someParameter"></select></div>'
Run Code Online (Sandbox Code Playgroud)
你只是在没有curlies的情况下完成它,它会绑定.我的猜测是父作用域绑定到子作用域中的someParameter,然后select绑定到子作用域中的somParameter.
因此,下面关于在链接函数中手动编译的所有这些都不是必需的.
=====
但问题是我的citySelect指令有一个硬编码的ng-model绑定,所以如果我创建了某种通用的widget,我就不能在表单中使用多个.不幸的是,这似乎不起作用:
scope: {someParameter: "="},
template: '<div><select ng-model="{{ someParameter }}"></select></div>'
Run Code Online (Sandbox Code Playgroud)
我实现这一点的唯一方法是在链接函数中手动构建DOM元素,但我不确定这是否可取.我很感激任何人对此实施的评论:
<body ng-app="TestApp">
<form ng-controller="FormCtrl" name="testForm">
<input name="firstInput" ng-model="data.first">
<input name="secondInput" ng-model="data.second">
<div city-select bind-to="data.homeCity"></div>
<div city-select bind-to="data.workCity"></div>
<button ng-click="submit()">Submit</button>
</form>
</body>
app.directive('citySelect', function($compile) {
return {
replace: true,
template: '<div></div>',
controller: function($scope) {
// Omitting the logic for getCities(), but it'd go here
}
link: function(scope, iElem, iAttrs) {
var html = '<div><select ng-bind="' + iAttrs['bindTo'] + '"></div>';
iElem.replaceWith($compile(html)(scope));
}
};
})
Run Code Online (Sandbox Code Playgroud)
由于为每个表单创建了FormCtrl的单独实例,因此可以重用FormCtrl中的许多功能.但您也可以在表单标记上使用其他指令来添加参数或拆分功能.例如:
<form ng-controller="FormCtrl" name="testForm" post-form post-path="/path/to/resource/">
app.directive('postForm', function() {
return {
controller: function($scope) {
$scope.post = function() {
// Some generic POST behavior
};
},
link: function(scope, iElem, iAttr) {
scope.postPath = iAttr['postPath'];
},
};
});
Run Code Online (Sandbox Code Playgroud)
然后,表单的作用域将组合FormCtrl和postForm的作用域,以便可以访问所有内容.在我的实验中,似乎FormCtrl优先,所以如果在FormCtrl和postForm中都定义了类似$ scope.submit()的东西,FormCtrl将优先(我认为),也许这是异步加载的竞争条件,我不知道.
我认为你也可以scope:true在mixin指令(postForm)上使用,或者更安全地使用ng-controller,而不是使用ng-controller scope: {}.
| 归档时间: |
|
| 查看次数: |
10414 次 |
| 最近记录: |