gpt4 book ai didi

angularjs - 使用 ControllerAs 时 Angular 嵌套指令出现问题

转载 作者:行者123 更新时间:2023-12-03 08:14:21 24 4
gpt4 key购买 nike

我正在构建一个巨大的表单,它调用各种指令来构建一个完整的表单。调用 Form Builder 的主页像这样传递 ng-model 数据:

<div form-builder form-data=“formData”></div>

然后表单构建器页面调用各种子指令来构建表单的各个部分:

FormBuilder.html:

<div form-fields></div>
<div photo-fields></div>
<div video-fields></div>
.. etc.. etc...

使用 $scope 时在 Controller 中,我可以毫无问题地访问 $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 ,我在访问与父子 Controller 的双向绑定(bind)时遇到了各种麻烦。

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

无论我尝试什么,我都会遇到障碍。我尝试过的事情是:

  1. 独立范围:我尝试传递 formData.formFieldsformData.photoFields作为子指令的独立范围,但我最终得到了 $compile: MultiDir错误由于嵌套的隔离范围,所以这是不可能的。
  2. 如果我没有每个表单部分的单独指令,并将它们全部放在formBuilder 下的 1 条指令指令,那么它就变成了巨大的指令。以上只是一个草图,但每个 child 指令最终构建了 1 个大表格。所以合并它们在一起真的是最后的手段,因为它确实变得很难维护和不可读。
  3. 我认为没有办法访问父指令的 ControllerAs来自 child 指令的 Controller任何其他方式从我到目前为止所看到的。
  4. 如果我使用父级的 ControllerAs子指令模板的 ng-model 类似 <input type=“text” ng-model=“fb.formData.formFields.text" /> ,效果很好,但我需要从 Child 指令的 Controller 访问相同的一些我无法做的处理。
  5. 如果我摆脱 controllerAs并使用 $scope再次,它像以前一样工作,但我是试图摆脱 $scope完全是为了自己准备 future 的 Angular 变化。

由于它是一种高级表单,我需要有单独的指令来处理各种表单部分,并且由于自 Angular 1.2 以来不允许使用嵌套的独立作用域,因此它变得越来越难,尤其是在试图摆脱 $scope 时。使用 ControllerAs .

有人可以指导我在这里我有哪些选择吗?感谢您阅读我的长篇文章。

最佳答案

基本上你需要使用指令的require选项(require选项用于指令与指令的通信)。这将通过在子指令中提及 require 选项来访问其父 Controller 。此外,您还需要使用 bindToController: true,这基本上会将独立的作用域数据添加到指令 Controller 。

代码

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 选项,您可以在链接函数的第 4 个参数中获取该指令的 Controller 。

代码

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);
})
}
}
}

编辑

上述解决方案的一个问题是,为了在指令 Controller 中访问父指令的 Controller ,我做了一些技巧。第 1 步将 formBuilderCtrl 包含到链接函数第 4 个参数的范围变量中。然后只有您可以使用 $scope(您不想在那里)访问该 Controller 。关于登录的相同问题 Github with open status ,您可以在此处查看。

关于angularjs - 使用 ControllerAs 时 Angular 嵌套指令出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34116637/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com