我正在尝试创建一些可以包装布局的指令,以便我可以从该布局中抽象出来(据我所知,这是指令的主要目标之一)。
所以我想要的是这样的:
<dialog>
<dialog-title></dialog-title>
<dialog-body></dialog-body>
<dialog-footer></dialog-footer>
</dialog>
我为此创建了 3 个简单的指令,看起来与此类似
app.directive('dialog', ()=>{
return {
template: '<div class="dialog" ng-transclude></div>',
replace: true,
transclude: true,
restrict: 'E',
}
})
然后我想确保在一个指令(对话框体)中定义的模型将在另一个(对话框页脚)中可见,因为我需要该对话框上的一些表单和页脚中的一些导航按钮,这些按钮可能被禁用,不取决于任何一个该表格有效与否。
<body ng-controller="MainCtrl">
<p>age: {{age}}</p>
<dialog>
<p>age: {{age}}</p>
<dialog-body>
<form name="dialogForm">
<p>age: {{age}}</p>
<input ng-model="age" minlength="3"/>
</form>
</dialog-body>
<dialog-footer>
<p>age: {{age}}</p>
</dialog-footer>
</dialog>
</body>
ng-model
在 dialog-body
将在对话框主体的范围内创建年龄变量,但它不会出现在其他指令中,直到我将它放入对象并在 MainCtrl
中声明.这是它的工作原理: <body ng-controller="MainCtrl">
<p>age: {{user.age}}</p>
<dialog>
<p>age: {{user.age}}</p>
<dialog-body>
<form name="dialogForm">
<p>age: {{user.age}}</p>
<input ng-model="user.age" minlength="3"/>
</form>
</dialog-body>
<dialog-footer>
<p>age: {{user.age}}</p>
</dialog-footer>
</dialog>
</body>
和 Controller :
app.controller('MainCtrl', function($scope) {
$scope.user = {age: 1}
})
现在,我想在
dialog-body
中输入一个表格.这应该在对话框体的范围内创建 FormController,就像 ng-model
做了(或者这里有一些区别?)。我需要从对话框页脚访问它来检查表单的有效性。因此,在模板中创建表单后,我需要在 MainCtrl 的范围内定义 formController,这是第一个问题 - 如何创建 FormController 的实例?我以为
$scope.dialogForm = {$valid: true}
应该用于测试目的,这是我的最终模板: <body ng-controller="MainCtrl">
<p>age: {{user.age}}</p>
<p>validity: {{dialogForm.$valid}}</p>
<dialog>
<p>age: {{user.age}}</p>
<p>validity: {{dialogForm.$valid}}</p>
<dialog-body>
<form name="dialogForm">
<p>age: {{user.age}}</p>
<p>validity: {{dialogForm.$valid}}</p>
<input ng-model="user.age" minlength="3"/>
</form>
</dialog-body>
<dialog-footer>
<p>age: {{user.age}}</p>
<p>validity: {{dialogForm.$valid}}</p>
</dialog-footer>
</dialog>
</body>
主要问题来了。当
dialog-body
中的表单有效性更改时它没有反射(reflect)在其他指令中。为什么?我在这里想念什么?我的主要目标是为应用程序中最常用的组件提供指令,以便我可以从实际布局中抽象出来——这可以用不同的方式完成吗?
这里是 plunk
最佳答案
When form validity changes in dialog-body it does not reflect in other directives. Why?
在您的指令中
transclude: true
将创建一个新范围并从父级 scope
继承在这种情况下是 MainCtrl
的范围.据我所知,当您声明 <form name="dialogForm">
, angular 会将 formController 绑定(bind)到 dialogBody
的嵌入范围,即对于 dialogBody
它会做$scope.dialogForm = formController
并且因为它是一个新的范围,其他被嵌入的范围将不会看到这种变化。要解决此问题,您可以在父作用域中声明一个共享变量或使用 controller as语法本质上是一样的。
<body ng-controller="MainCtrl as vm">
然后将表单绑定(bind)到
vm
<form name="vm.dialogForm">
<p>age: {{vm.user.age}}</p>
<p>validity: {{vm.dialogForm.$valid}}</p>
<input ng-model="vm.user.age" minlength="3"/>
</form>
见 plunker
为什么这行得通?因为所有新的嵌入范围都继承了
vm
来自父作用域和 formController vm.dialogForm
绑定(bind)到这个公共(public)变量,所以所有被嵌入的范围都会看到这个变化。
关于angularjs - 嵌入指令和表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44049216/