1

I have a pretty large angular project, I'm using a lot of directives which all work fine. I followed a best practice guide which mentioned using controllerAs: vm (view model) instead of $scope.

This has worked fine throughout the project, however in one directive in particular, the vm doesn't seem to be callable within my partial.

Directive:

 (function() {
  "use strict";

  angular.module('bandzest.directive.create.release', [])
         .directive('createRelease', CreateRelease);

  function CreateRelease() {

    var directive = {
      link: link,
      restrict: 'E',
      templateUrl: './app/components/release/partial.create.release.html',
      controller: function(content, $cookies, $scope, $rootScope) {

        var vm = this;
        vm.save = save;

        vm.release = {         
          artist: $cookies.get('artistId')        
        };

        vm.files = [];
        vm.tracks = [];

        $scope.$on("fileSelected", function (event, args) { 
          $scope.$apply(function () {
            vm.files.push(args.file);
          });
        });

        function save() {

          $http({
            method: 'POST',
            url: api+"/api/v1/releases",
            headers: { 'Content-Type': undefined },
            transformRequest: function (data) {
            var formData = new FormData();

            formData.append("release", angular.toJson(data.release));

            for (var i = 0; i < data.files.length; i++) {
              formData.append("file" + i, data.files[i]);
            }

            return formData;
          },
            data: { release: $scope.release, files: vm.files },
            params: { user: $cookies.userId }
          }).success(function (data, status, headers, config) {
            console.log(data);
          }).error(function (data, status, headers, config) { 
            console.log(data);
          });
        }
      },
      controllerAs: 'vm',
      bindToController: true
    }

    return directive;

    function link() {

    }
  }
})();

Partial:

<div class="index-header">
    <ul>
      <li><a trigger-upload class="primary">+ Upload tracks</a></li>
        <li><a href="#">Cancel</a></li>
    </ul>
    <div class="clear"></div>

  <div class="release-creation">

<div class="release-section-title">Release Information</div>
      <div class="release-section">
        <div class="release-create-artwork">
      <img src="img/artwork.jpg" alt="">
    </div>

    <div class="release-create-basic-information">
      <div class="release-create-column">
        <input autofocus placeholder="Release title" type="text" ng-model="vm.release.title" class="input">
        <input ng-model="vm.release.genre" id="release-create-genre" placeholder="Genres (comma separated)" type="text" class="input">
        <textarea ng-model="vm.release.tags" id="release-create-tags" placeholder="Tags (comma seperated)" class="input textarea"></textarea>
      </div>

      <div class="release-create-column">
        <div class="release-date-choice">
          <div class="release-date-option">
            <input ng-model="vm.release.releaseDate" checked name="release-date" id="release-radio-current" type="radio" class="release-radio">
            <label for="release-radio-current">Current date</label>
          <div class="clear"></div>
        </div>

        <div class="release-date-option">
          <input ng-model="vm.release.releaseDate" name="release-date" id="release-radio-future" type="radio" class="release-radio">
          <label for="release-radio-future">Use a different release date</label>
          <div class="clear"></div>
        </div>
      </div>
                        <div class="release-create-date">
                            <input disabled placeholder="DD" type="text" class="input input-day">
                            <input disabled placeholder="MM" type="text" class="input input-month">
                            <input disabled placeholder="YYYY" type="text" class="input input-year">
                        </div>
                        <textarea ng-model="vm.release.description" placeholder="Description" class="input textarea"></textarea>

                    </div>
                </div>
                <div class="clear"></div>
            </div>
            <div class="release-section-title">Pricing</div>
            <div class="release-section">
                <div class="release-pricing">
                    <div class="release-input">
                        <div class="form-group release-price">
                            <label for="whole-release-price">Whole release price</label>
                            <input ng-model="vm.release.releasePrice" id="whole-release-price" type="number" class="input">
                        </div>
                        <div class="form-group track-price">
                            <label for="single-track-price">Single track price</label>
                            <input ng-model="vm.release.trackPrice" id="single-track-price" type="number" class="input">
                        </div>
                        <div class="form-group clear">
                            <input ng-model="vm.release.payMore" id="pay-more" type="checkbox" value="false">
                            <label for="pay-more">Let people pay more if they want?</label>
                        </div>
                    </div>
                    <div class="clear"></div>
                </div>
            </div>
            <div class="release-section-title">Track List</div>
            <div class="release-section">
                <input id="track-upload" type="file" file-upload class="hidden" multiple>
                <div class="track-list"> 
                    <ul ng-sortable="{ group: 'tracks', animation:150 }" id="release-track-list">
                        <li style="display:none;"></li>
                    </ul>
                </div>
          </div>
      </div>
  </div>
  <button class="btn btn-primary" ng-click="vm.save">Submit</button>

And my routes (notice the /releases/create doesn't have a controller as it's using a directive)

angular.module('bandzest.routes.release', [])
.config(ReleaseRouter);

ReleaseRouter.$inject = ['$routeProvider', '$locationProvider', 'USER_ROLES'];

function ReleaseRouter($routeProvider, $locationProvider, USER_ROLES) {

  $routeProvider
  .when('/releases/create', {
    templateUrl: '/app/components/release/view.create.release.html',
    data: {
      authorisedRoles: [USER_ROLES.guest, USER_ROLES.user, USER_ROLES.artist]    
    }
  })
  .when('/releases/:id', {
    templateUrl: '/app/components/release/view.show.release.html',
    controller: 'ReleaseController',
    controllerAs: 'vm',
    data: {
      authorisedRoles: [USER_ROLES.guest, USER_ROLES.user, USER_ROLES.artist]    
    }
  })
  .when('/releases', {
    templateUrl: '/app/components/release/view.index.release.html',
    controller: 'ReleaseController',
    controllerAs: 'vm',
    data: {
      authorisedRoles: [USER_ROLES.guest, USER_ROLES.user, USER_ROLES.artist]  
    }
  });
}

When I hit the submit button, nothing happens. I took all of the code out of the partial and replaced it with a simple ng-click to a function in the directive writing something to the console and that didn't work either.

Finally, the view calling the directive:

<artist-menu></artist-menu>
<section class="page-content">
    <div class="releases-container">
      <create-release></create-release>
    </div>
</section>

1 Answer 1

2

The ng-click directive takes an "expression to evaluate upon click". What you are giving it is a reference. Have you tried the following?

<button class="btn btn-primary" ng-click="vm.save()">Submit</button>
Sign up to request clarification or add additional context in comments.

1 Comment

Doh! You got it in one! Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.