Fred A
Fred A

Reputation: 1764

Few questions regarding controllerAs

As much as i have read all the questions in SO, i still have few questions here around the controllerAs, using generic widget directive below as example

var app = angular.module('test')
app.directive('genericDirective', function(){
  return {
      restrict:'E',
      templateUrl: someUrlHere,
      scope: { someScopeHere },
      controllerAs: 'vm',
      bindToController: true,
      controller: function(){
         someControllerHere
      }
  }
})

And the template for the directive above is

<div>{{info1}} {{info2}} {{info3}}</div>

And say there are like few directives above (genericDirective2, genericDirective3 and so on) that uses same setup as above. My idea here is to have a generic directive that can be plug-in into any view and works with any controllers that handle the view which the directive above is in.

So say if i have a layout below

<div id="someId" ng-controller="thisController">
    <!-- Widget one -->
    <generic-directive1></generic-directive1>
    <!-- Widget two -->
    <generic-directive2></generic-directive2>
    <!-- Widget three -->
    <generic-directive3></generic-directive3>
</div>

Assume that thisController gets a json, which contains all the data needed to render each directive accordingly

{
    "generic-directive-1": {
        "id": "someId1",
        "class": "someClass1",
        "data": {
            "info1":"someInfo1-1",
            "info2":"someInfo1-2",
            "info3":"someInfo1-3"
        }
    },
    "generic-directive-2": {
        "id": "someId2",
        "class": "someClass2",
        "data": {
            "info1":"someInfo2-1",
            "info2":"someInfo2-2",
            "info3":"someInfo2-3"
        }
    },
    "generic-directive-3": {
        "id": "someId3",
        "class": "someClass3",
        "data": {
            "info1":"someInfo3-1",
            "info2":"someInfo3-2",
            "info3":"someInfo3-3"
        }
    }
}

How can i make it so that

Upvotes: 2

Views: 68

Answers (1)

gyc
gyc

Reputation: 4360

How can i make it so that thisController can access to specific genericDirective using the controllerAs (in this case using controllerAs: 'vm'), say if i want to pass specific params from thisController to generic-directive-3, how can i do it?

Since you're not using components, the cleanest way to share data between controllers is by using services. You also have other choices.

In the case of directives, you can / should pass data through attributes:

<div id="someId" ng-controller="thisController">
    <generic-directive1 data="obj.generic-directive-1"></generic-directive1>
    <generic-directive2 data="obj.generic-directive-2"></generic-directive2>
    ...
</div>

This data will be bound to the scope of the directive or to the directives's controller. I wouldn't personnaly use them together as it can become confusing:

  return {
      restrict:'E',
      template: '<p>{{data.id}}</p>',
      scope: { data: '=' }
  }

or

  return {
      restrict:'E',
      template: '<p>{{vm.data.id}}</p>',
      bindToController: { 'data: '=' },
      controllerAs: 'vm',
      controller: function() {
         console.log(this.data); //data is bound to the controller
      }
  }

The right directive will get the right data from thisController? Since i set all directives with controllerAs:'vm'.

The directive will get the data through the scope if an isolated scope is used or directly through the controller if bindToController is used.

Do i need to use different controllerAs name for each directive? As 2-3 of the directives with the same controllerAs might be used within a page, and the page controller might be referring to the wrong directive?

You don't have to use a different name for the controllerAs property as it's only used inside the directive.

However in order to avoid repeating controller code, you cannot declare it as n anonymous function inside the directive but rather like so:

function UniqueController() {
  console.log("hello");
}

function myDirective1() {
  return {
      restrict:'E',
      template: '<p>{{vm.data.id}}</p>',
      bindToController: { 'data: '=' },
      controllerAs: 'vm',
      controller: UniqueController
  }
}

angular.module('mymodule', []);
angular.module('mymodule')
    .directive('myDirective1', myDirective1)
    .directive('myDirective2', myDirective2)
    .controller('UniqueController', UniqueController);

Upvotes: 1

Related Questions