Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to observe custom events in AngularJS?

Simple example: I have a textarea and want to provide additional behavior to it: do something on enter key and go to next line on shift + enter

I suppose that I should provide additional directive to add that behavior. And I've done this: http://jsbin.com/oruvuy/1/edit

P.S. One hackie thing seems strange for me: I invoke $digest() manually. Is it ok? Any thoughts?

JS:

angular.module('Chat', [])
  .directive('enterSubmit', function () {
    return {
      restrict: 'A',
      link: function (scope, element, attrs) {
        var submit;

        $(element).on({
          keydown: function (e) {
            submit = false;

            if (e.which === 13 && !e.shiftKey) {
              submit = true;
              e.preventDefault();
            }
          },

          keyup: function () {
            if (submit) {
              scope.$eval( attrs.enterSubmit );

              // flush model changes manually
              scope.$digest();
            }
          }
        });
      }
    };
  });

function ChatCtrl($scope) {
  $scope.messages = [{
    text: 'Sample Message',
    datetime: new Date()
  }];

  $scope.add = function () {
    $scope.messages.push({
      text: $scope.message,
      datetime: new Date()
    });
    $scope.message = '';
  };

  $scope.message = '';
}
<body ng-controller="ChatCtrl">

  <h1>Leave message:</h1>
  <form>
    <div class='hint'>Click &lt;Enter&gt; to submit :)</div>
    <textarea
      cols="30"
      rows="5"
      ng-model="message"
      enter-submit='add()'
    ></textarea>
    <br />
    <button type="submit" ng-click="add()">Send message!</button>
  </form>

  <h3>Messages list:</h3>
  <table>
    <tr>
      <th>Text</th>
      <th>Date</th>
    </tr>
    <tr ng-repeat="message in messages">
      <td class='text'>{{message.text}}</td>
      <td class='date'>{{message.datetime | date:"HH:mm:ss"}}</td>
    </tr>
  </table>

</body>

But is it correct way to do that?

like image 487
ValeriiVasin Avatar asked Feb 17 '13 20:02

ValeriiVasin


1 Answers

Yes, binding events in the directive's linking function is exactly what you want to do.

Calling $digest is not hacky - the messages in your example are being added to the model on keyup, and Angular won't digest those changes until something tells it to. It will actually be digested on the next keydown, but since you need the $digest to happen after your keyup, you're having to call it manually.

like image 197
jingman Avatar answered Oct 09 '22 06:10

jingman