我正在构建一个巨大的表单,它调用各种指令来构建完整的表单。调用表单生成器的主页传递ng模型数据,如下所示:
body
然后,Form Builder Page调用各种子指令来构建Form的各个部分:
<div form-builder form-data=“formData”></div>
在控制器中使用FormBuilder.html:
<div form-fields></div>
<div photo-fields></div>
<div video-fields></div>
.. etc.. etc...
时,访问子指令中的$scope
是没有问题的:
$scope
但是自从我摆脱了function formBuilder() {
return {
restrict: 'A',
replace: true,
scope: {
formData: '='
},
templateUrl: 'FormBuilder.html',
controller: function($scope) {
$scope.formSubmit = function() {
// Submits the formData.formFields and formData.photoFields
// to the server
// The data for these objects are created through
// the child directives below
}
}
}
}
function formFields() {
return {
restrict: 'A',
replace: true,
templateUrl: 'FormFields.html',
controller: function($scope) {
console.log($scope.formData.formFields);
}
}
}
function photoFields() {
return {
restrict: 'A',
replace: true,
templateUrl: 'PhotoFields.html',
controller: function($scope) {
console.log($scope.formData.photoFields);
}
}
}
... etc..
并开始使用$scope
之后,我遇到了与父 - 子控制器进行双向绑定的各种麻烦。
ControllerAs
无论我尝试什么,我都会遇到路障。我尝试过的事情是:
function formBuilder() {
return {
restrict: 'A',
replace: true,
scope: {
formData: '='
},
templateUrl: 'FormBuilder.html',
controller: function() {
var vm = this;
console.log(vm.formData); // Its fine here
vm.formSubmit = function() {
// I cannot change formData.formFields and formData.photoFields
// from Child Directive "Controllers"
}
},
controllerAs: ‘fb’,
bindToController: true
}
}
function formFields() {
return {
restrict: 'A',
replace: true,
templateUrl: 'FormFields.html',
controller: function() {
var vm = this;
console.log(vm.formData.formFields);
// No way to access 2 way binding with this Object!!!
}
}
}
function photoFields() {
return {
restrict: 'A',
replace: true,
templateUrl: 'PhotoFields.html',
controller: function() {
var vm = this;
console.log(vm.formData.photoFields);
// No way to access 2 way binding with this Object!!!
}
}
}
和
formData.formFields
作为child指令的独立范围,
但是我最终得到了formData.photoFields
错误
嵌套的隔离范围,因此无法实现。 $compile: MultiDir
指令下的1指令,然后它变成了
无耻的指示。以上只是一个草图,但每个孩子
指令构建最终放在一起的1大表。所以合并他们
一起真的是最后的手段,因为它变得很难
维持和不可读。 formBuilder
的父指令ControllerAs
以任何其他方式
从我到目前为止看到的。 Controller
一样,工作正常,但我
需要从Child指令的控制器访问相同的
一些我无法做的处理。 <input type=“text” ng-model=“fb.formData.formFields.text" />
然后再次使用controllerAs
,它就像以前一样,但我是
试图完全摆脱$scope
为自己做好准备
未来的角度变化。由于它是一个高级表单,我需要有单独的指令来处理各种表单部分,因为自Angular 1.2以来不允许嵌套的隔离作用域,所以它使得它变得更加困难,尤其是在试图摆脱{{1}时使用$scope
。
有人可以指导我在这里有什么选择吗?我感谢你阅读我的长篇文章。
答案 0 :(得分:2)
基本上你需要使用require
指令选项(require
选项用于指令的通信指令)。只需在child指令中提及require
选项,即可访问其父控制器。您还需要使用bindToController: true
,它基本上将隔离的范围数据添加到指令控制器。
<强>代码强>
function formBuilder() {
return {
restrict: 'A',
replace: true,
bindToController: true,
scope: {
formData: '='
},
templateUrl: 'FormBuilder.html',
controller: function($scope) {
$scope.formSubmit = function() {
// Submits the formData.formFields and formData.photoFields
// to the server
// The data for these objects are created through
// the child directives below
}
}
}
}
然后,您需要向子指令添加require
选项。基本上,require
选项将formBuilder
指示^
(表示formBuilder
将在父元素中),例如require: '^formBuilder',
。
通过编写require
选项,您可以在链接函数4th参数中获取该指令的控制器。
<强>代码强>
function formFields() {
return {
restrict: 'A',
replace: true,
require: '^formBuilder',
templateUrl: 'FormFields.html',
//4th parameter is formBuilder controller
link: function(scope, element, attrs, formBuilderCtrl){
scope.formBuilderCtrl = formBuilderCtrl;
},
controller: function($scope, $timeout) {
var vm = this;
//getting the `formData` from `formBuilderCtrl` object
//added timeout here to run code after link function, means after next digest
$timeout(function(){
console.log($scope.formBuilderCtrl.formData.formFields);
})
}
}
}
function photoFields() {
return {
restrict: 'A',
replace: true,
require: '^formBuilder',
templateUrl: 'PhotoFields.html',
//4th parameter is formBuilder controller
link: function(scope, element, attrs, formBuilderCtrl){
scope.formBuilderCtrl = formBuilderCtrl;
},
controller: function($scope, $timeout) {
var vm = this;
console.log(vm.formData.photoFields);
//to run the code in next digest cycle, after link function gets called.
$timeout(function(){
console.log($scope.formBuilderCtrl.formData.formFields);
})
}
}
}
修改强>
上述解决方案的一个问题是,为了在指令控制器中访问父指令的控制器它自己,我做了一些棘手的事情。 1st包含来自link function 4th参数的范围变量的formBuilderCtrl
。然后,只有您可以使用$scope
(您不希望在那里)访问该控制器。关于Github with open status中记录的同一问题,您可以在此处查看。