0

Angular noob here. I'm trying to create a form as a directive. ng-submit calls a controller action, but, within that method, I don't have access to the controllers scope, ie. $scope.

Here's the part that's really confusing me. On my laptop and my desktop, the first time I dropped into debugger within the submit(), $scope was still in scope. Every subsequent time, it's not.

I had a coworker test this code, and they can't reproduce it.

EDIT: If I do not drop into debugger at that point in $scope.submit it works fine.

course-material-form.js.coffee

angular
  .module 'app'
  .directive 'courseMaterialForm', () ->
    restrict: 'EA'
    templateUrl: 'app/shared/coursework/course-material/templates/_form.html'
    scope:
      book: '='
      model: '='
    controller: 'CourseMaterialFormCtrl'

course-material-form-ctrl.js.coffee

angular
  .module 'app'
  .controller 'CourseMaterialFormCtrl', ($scope) ->
    $scope.submit = () ->

    return

_form.html.haml

%form.form-compact#course-material-form{ "ng-submit" => "submit()" }
  %fieldset.row
    .form-group.col-xs-12
      %label Title
      %input{ type: 'text', "ng-model" => " book.title " }

    .form-group.col-md-6.col-xs-12
      %label Author
      %input{ type: 'text', "ng-model" => " book.author " }

  %fieldset.row
    .form-group.col-md-6.col-xs-12
      %label Publisher
      %input{ type: 'text', "ng-model" => " book.publisher " }

    .form-group.col-md-6.col-xs-12
      %label Publication Year
      %input{ type: 'text', "ng-model" => " book.publication_date " }

    .form-group.col-md-6.col-xs-12
      %label Edition
      %input{ type: 'text', "ng-model" => " book.edition " }

    .form-group.col-md-6.col-xs-12
      %label ISBN
      %input{ type: 'text', "ng-model" => " book.isbn " }

  %fieldset.row
    .form-group.col-xs-12
      %label Description
      %textarea{ "ng-model" => "book.description" }

  %fieldset.row.hidden
    .form-group.col-md-6.col-xs-6
      %label URL
      %input{ type: 'text' }

_modal.html.haml

.modal-dialog.modalbox-dialog.coursework-form-modal
  .modal-content

    %header.modal-header.modal-header-lg
      .modal-heading
        %span{ "ng-if" => "!book" } Add
        %span{ "ng-if" => "book" } Edit
        Course Material

      %button.modal-close-btn.modal-close-icon{ "ng-click" => "$dismiss()" }
        %i.fa.fa-times-circle

    .modal-body
      %course-material-form{ model: "model", book: "book" }

    .modal-footer
      %button.btn.btn-primary.modal-footer-btn{ form: "course-material-form",
                                                type: "submit" }
        %span{ "ng-if" => "!book" } Create
        %span{ "ng-if" => "book" } Save
      %button.btn.btn-outline.modal-footer-btn{ "ng-click" => "$dismiss()",
                                                type: "button" }
        Close
1
  • I suggest to reduce the lines of codes while you constantly check whether the error is still there. This is still quite much of code right now. Commented Jun 8, 2015 at 23:48

2 Answers 2

1

The submit function from your controller and from your directive are not the same. They belong to different $scope. More info about it on section "Isolating the Scope of a Directive" from the Directive's guide

Since you are isolating the scope for the directive, you should "expose" the submit function from your controller to your directive like that:

scope: {
    book: '=',
    model: '=',
    submit: '&' // <- that's what you need
}

Then on your _modal.html, pass the a new attribute:

.modal-body
    %course-material-form{ model: "model", book: "book", submit: "submit()" }
Sign up to request clarification or add additional context in comments.

2 Comments

Are you sure that's the problem? Shouldn't the $scope of the controller be exposed in the associated directive?
That would limit the power of directives. You don't want always to expose the Controller $scope to a directive, in case directives are under a ngRepeat, things would get trickier. If you want to reuse the Ctrl's $scope, set scope to true instead of passing a object. However, you will get in other problems later. Read the section "Isolating the Scope of a Directive" on this page here: docs.angularjs.org/guide/directive
0

I don't know if this qualifies as an answer. I was not actually calling $scope from within the controller method. If you $scope.book then $scope is available in the debugger.

Comments

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.