angularjs - 嵌入指令和表格

标签 angularjs angularjs-directive angularjs-ng-transclude

我正在尝试创建一些可以包装布局的指令,以便我可以从该布局中抽象出来(据我所知,这是指令的主要目标之一)。

所以我想要的是这样的:

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

相关文章:

javascript - 从 AngularJs 指令调用函数

angularjs - ui-grid 内的下拉打开问题

javascript - AngularJS:在编译之前获取指令内容

javascript - ng 嵌入为 : element vs attribute

javascript - 如何使用指令在 Angularjs 中单击按钮时创建选择选项

angularjs - 检测 Angular 指令中不可分配的值

javascript - 当 AngularJS 中的路由发生变化时,如何保留资源数据?

javascript - 如何防止 Angular 数组更新闪烁

AngularJS : How to transclude and have both isolate scope and parent scope?

javascript - angularjs 指令检查是否最小。复选框列表中的一项被选中