_
_
_ _2013-07-06 21:18:31
Yii
_ _, 2013-07-06 21:18:31

AngularJS: how directives interact - emit, broadcast, controller require?

Good afternoon.
I'm fiddling with AngularJS. I read the documentation, now I'm working on examples from real life in conjunction with Yii
Actually, an example:
There are two directives - a form and a modal window. The form is a wrapper over ActiveForm from Yii.
The form can either exist on its own or be nested in a modal window:

<modal-dialog><br>
     <active-form><br>
     </active-form><br>
</modal-dialog><br>

The modal dialog can handle the click event on the confirm button. The form can do validation on the server and receive validation results as an event.
I would like the modal dialog to be able to notify the form that it was confirmed, and the form, in turn, could ask the dialog to close, for example. At the same time, the form should remain working, being on its own, without a modal dialogue.
After trying several approaches, I settled on using require in the directive:
angular.module('app').directive 'activeForm', (yiiscripts) -><br>
  scope: 'isolated'<br>
  replace: false<br>
  transclude: false<br>
  require: ['activeForm','?^modalDialog']<br>
  controller: ($scope, $element) -><br>
    onSubmit: ($form, modalDialogController) -><br>
      modalDialogController.startLoading() if modalDialogController<br>
      $element.submit()<br>
    afterValidate: ($form,data,hasErrors,modalDialogController) -><br>
      modalDialogController.endLoading() if modalDialogController<br>
      modalDialogController.close() if !hasErrors and modalDialogController<br>
      !hasErrors<br><br>
  link: ($scope, element, attrs, controllers) -><br>
    [myController, modalDialogController] = controllers<br>
    yiiscripts.activeform element.attr('id'),<br>
      afterValidate: ($form, data, hasErrors) -><br>
        myController.afterValidate($form,data,hasErrors,modalDialogController)<br><br>
    if modalDialogController and modalDialogController.listenSubmit<br>
      modalDialogController.listenSubmit -><br>
        myController.onSubmit(element, modalDialogController)<br>

angular.module('app').directive 'modalDialog', (templates) -><br>
  scope:<br>
    title: '@modalTitle'<br>
    modalOk: '@modalOk'<br>
    modalCancel: '@modalCancel'<br>
  replace: true<br>
  transclude: true<br>
  template: $('#modal_dialog_template').html()<br>
  controller: ($scope) -><br>
    submitListeners = []<br>
    controller =<br>
      listenSubmit: (listener) -><br>
        submitListeners.push(listener)<br>
      onSubmit: (evt) -><br>
        evt.preventDefault()<br>
        $.each submitListeners, -> this.apply(evt)<br>
      startLoading: -><br>
        $scope.$broadcast('startLoading')<br>
      endLoading: -><br>
        $scope.$broadcast('endLoading')<br>
      close: -><br>
        $scope.$broadcast('close')<br>
    controller<br><br>
  link: ($scope, element, attrs, controller) -><br><br>
    element.css({display:'block'})<br>
      .modal(show: false)<br>
    $scope.$on 'close', -> element.modal('hide')<br>
    $scope.$on 'startLoading', -> element.modal('loading')<br>
    $scope.$on 'endLoading', -> element.modal('loading')<br>
    $('input[type="submit"]',element).click(controller.onSubmit)<br>

When linking, the form requests a modal dialog controller higher in the hierarchy, if it exists (require ["?^modalDialog"])
If it exists, it is added to the subscribers to the dialog submit message.
When it receives a submit message, it puts the dialog in the loading state and starts submitting the form itself.
After validation, the onAfterValidate message is triggered on the server, where we cancel the data loading state for the dialog and continue as standard for the Yii form.
Everything works as expected, including for the form separately. I would like to know how this approach fits into the AngularJS development guides. I tried to use $scope.$emit, $scope.$broadcast to exchange messages between directives (the form does $scope.$emit on its events, $scope.$broadcast dialog on its own), but for directives I need isolated scope and in In this case, the form's $scope is not a child of the dialog's $scope, so messages are passed by.
Thanks in advance.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
E
EugeneOZ, 2013-07-07
@EugeneOZ

It fits perfectly (more: www.egghead.io/video/rzMrBIVuxgM ), only here

template: $('#modal_dialog_template').html()

does not fit :) IMHO, it is better to load such templates in the script so that there is no dependence on jQuery.

R
RodgerFox, 2015-07-02
@RodgerFox

Right for you: https://egghead.io/lessons/angularjs-directive-to-...
Sorry for the year of waiting =D

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question