angularjsscopecontrollerangularjs-controlleras

Can you use ControllerAs syntax within separate Controllers that share the same view?


QUESTION:

Can you use ControllerAs syntax within separate Controllers that share the same view?

ie: (var vm = this)?

DILEMMA

I'm trying to get rid of the linter error in my console generated by EsLinter:

"Designated alias 'vm' is not assigned to 'this' consistent-this" 

enter image description here

I would like to know how I can use : var vm = this within the controller or set the Controller as vm (I've tried both and it doesn't work)

The only thing that works is $scope within the controller (as seen below)... whenever I try to apply controller as syntax within the controller.js or the html div and apply the correlated variable (vm) to the interpolated expressions within the modal.html the data isn't rendered.

What is best practice for this?

** SIDE NOTE: I'm also having issues binding the ng-click action function to the view based on controller... the below examples do not work (for the action)-- also if I change the {{::action}} to {{::action()}} the function fires on load and not on click:

Example modal.html:

<article>
    <h1>{{::title}}</h1>
    <p>{{::body}}</p>
    <button ng-click="{{::action}}">{{::button}}</button>
</article>

HTML pulling in above ^

<div class="hide"
     ng-controller="ConfirmModalController"
     ng-include src="'/app/widgets/modals/modal.html'"></div>

<div class="hide"
     ng-controller="ErrorModalController"
     ng-include src="'/app/widgets/modals/modal.html'"></div>

Example Controllers

Error Controller

angular
  .module('common.modal')
  .controller('ErrorModalController', ErrorModalController);

function ErrorModalController(modalService, $scope) {

  var vm = $scope;

  vm.title = 'There was an error with your request';

  vm.body = 'Please contact adminstrator regarding this error';

  vm.button = 'Dismiss';

  vm.action = function () {
    console.log("closing modals");
    modalService.closeAllModals();
  };

}

Confirm Controller

angular
  .module('common.modal')
  .controller('ConfirmModalController', ConfirmModalController);

function ConfirmModalController(modalService, $scope) {

  var vm = $scope;

  vm.title = 'Confirm Your Subscription';

  vm.body = '$8.99 per month will be billed to your account.';

  vm.button = 'Subscribe';

  vm.action = function () {
    console.log("confirming subscription");
    modalService.confirmSubscription();
  };

}

Solution

  • Thank you for your suggestion @estus to create a directive for each type of modal - The data is now rendering correctly with vm=this ...

    And thank you to @JC-Ford for telling me how to fix the {{::action}} to vm.action() with no brackets ...

    ** SIDE NOTE: (still have the issue with the action button however)

    Solution main.html

    <confirm-modal></confirm-modal>
    

    Solution modal.html:

    <article>
        <h1>{{::vm.title}}</h1>
        <p>{{::vm.body}}</p>
        <button ng-click="vm.action()">{{::vm.button}}</button>
    </article>
    

    Solution confirm-modal.directive.js (and controller)

    angular
      .module('common.modal')
      .controller('ConfirmModalController', ConfirmModalController)
      .directive('confirmModal', confirmModal);
    
    /* @ngInject */
    function confirmModal() {
    
      var directive = {
        templateUrl: 'app/widgets/modals/modal.html',
        restrict: 'E',
        controller: ConfirmModalController,
        controllerAs: 'vm',
        bindToController: true
      };
    
      return directive;
    }
    
    function ConfirmModalController(modalService) {
    
      var vm = this;
    
      vm.title = 'Confirm Your Subscription';
    
      vm.body = '$8.99 per month will be billed to your account.';
    
      vm.button = 'Subscribe';
    
      vm.action = function () {
        modalService.confirmSubscription();
      };
    
    }
    

    Solution error-modal.directive.js (and controller)

    angular
      .module('common.modal')
      .controller('ErrorModalController', ErrorModalController)
      .directive('errorModal', errorModal);
    
    /* @ngInject */
    function errorModal() {
      var directive = {
        templateUrl: 'app/widgets/modals/modal.html',
        restrict: 'E',
        controller: ErrorModalController,
        controllerAs: 'vm',
        bindToController: true
      };
    
      return directive;
    }
    
    function ErrorModalController(modalService) {
    
      var vm = this;
    
      vm.title = 'There was an error with your request';
    
      vm.body = 'Please contact administrator regarding this error';
    
      vm.button = 'Dismiss';
    
      vm.action = function () {
        modalService.closeAllModals();
      };
    }