Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Forms AngularJS-带指令的模块化形式_Forms_Angularjs_Angularjs Directive - Fatal编程技术网

Forms AngularJS-带指令的模块化形式

Forms AngularJS-带指令的模块化形式,forms,angularjs,angularjs-directive,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.moreSpec

我最初问这个问题,但我想我超越了自己,把问题弄得比实际情况更复杂了,所以我在这里用了更清晰的措辞

如何创建具有指令和可重用参数的可重用表单小部件?像这样:

<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>

指令模板似乎不允许在ng模型上进行插值

此外,例如,您能否模块化和参数化表单行为,以便可以使用标准的POST操作


根据我的实验,我已经回答了下面的问题,但我暂时不接受它,因为我对Angular非常陌生,我想听听其他人的意见。

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>
这将为表单创建一个作用域,因为表单标记包含ng控制器标记。在这个范围内,
testForm
是表单的javascript对象,
testForm.firstInput
是第一个输入的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
        }
    };
})
app.directive('citySelect',function(){
返回{
替换:正确,
模板:“”+
'',
控制器:功能($scope){
//省略getCities()的逻辑,但它会出现在这里
}
};
})
然后你可以把它粘贴到表单标签中,它就可以工作了。因为指令没有定义作用域,所以它只会附加到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>

提交
指令参数化 编辑: 显然,这是可行的:

scope: {someParameter: "="},
template: '<div><select ng-model="someParameter"></select></div>'
作用域:{someParameter:=“},
模板:“”
你只要不带卷发就行了,它会粘在一起的。我猜父作用域绑定到子作用域中的someParameter,然后select绑定到子作用域中的somParameter

因此,下面所有关于在link函数中手动编译的内容都是不必要的

=====

但问题是我的citySelect指令有一个硬编码的ng模型绑定,所以如果我创建了某种通用小部件,我不能在表单中使用多个。不幸的是,这似乎不起作用:

scope: {someParameter: "="},
template: '<div><select ng-model="{{ someParameter }}"></select></div>'
作用域:{someParameter:=“},
模板:“”
我实现这一点的唯一方法是在链接函数中手动构建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));
        }
    };
})

提交
应用程序指令('citySelect',函数($compile){
返回{
替换:正确,
模板:“”,
控制器:功能($scope){
//省略getCities()的逻辑,但它会出现在这里
}
链接:功能(范围、iElem、iAttrs){
var html='';
用($compile(html)(scope))替换;
}
};
})
在窗体上混合参数 因为每个表单都创建了单独的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'];
        },
    };
});

app.directive('postForm',function(){
返回{
控制器:功能($scope){
$scope.post=函数(){
//一些通用的POST行为
};
},
链接:功能(范围、iElem、iAttr){
scope.postPath=iAttr['postPath'];
},
};
});
表单的作用域将合并FormCtrl和postForm的作用域,以便所有内容都可以访问。在我的实验中,似乎FormCtrl优先,所以如果在FormCtrl和postForm中都定义了$scope.submit()之类的东西,FormCtrl将优先(我想),可能这是异步加载的竞争条件,我不知道


我认为您也可以在mixin指令(postForm)上使用
scope:true
,而不是使用ng控制器,或者更安全地说,
scope:{}

这个相关问题中的一些附加注释有助于理解这一点:
<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'];
        },
    };
});