Transclusion directives and form

Viewed 253

I'm trying to create few directives which would wrap layout so I can abstract from that layout (which is one of the main goals of directives as I understand it).

So what I would like to have is something like this:

<dialog>
  <dialog-title></dialog-title>
  <dialog-body></dialog-body>
  <dialog-footer></dialog-footer>
</dialog>

I have created 3 simple directives for this which look similar to this

app.directive('dialog', ()=>{
  return {
    template: '<div class="dialog" ng-transclude></div>',
    replace: true,
    transclude: true,
    restrict: 'E',
  }
})

Then I want to ensure that models defined in one directive (dialog-body) will be visible in another (dialog-footer) because I would need some form on that dialog and some nav buttons in footer that may be disabled on not depending on either that form valid or not.

  <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 in dialog-body will create age variable in dialog-body's scope but it would not appear in other directives untill I put it in object and declare in MainCtrl. This is how it work:

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

and controller:

app.controller('MainCtrl', function($scope) {
  $scope.user = {age: 1}
})

Now, I want to put a form in dialog-body. That should create FormController on dialog-body's scope, just like ng-model did (or here are some difference?). And I need to have access to it from dialog-footer to check form validity.

So after creating form in template i need to define formController in MainCtrl's scope and here is first question - how do I create instance of FormController? I thought that $scope.dialogForm = {$valid: true} should work for testing purposes and here is my final template:

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

Here comes main problem. When form validity changes in dialog-body it does not reflect in other directives. Why? What am I missing here?

My main target is to have directives for most used components in application so that I will have abstraction from actual layout - can this be done in different way?

Here is the plunk

1 Answers
Related