如何在AngularJS中观察自定义事件?

时间:2022-02-13 23:55:55

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

简单示例:我有一个textarea,并希望为它提供额外的行为:在enter键上做一些事情,然后进入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

我想我应该提供额外的指令来添加那个行为。我已经这样做了:http://jsbin.com/oruvuy/1/edit

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

对我来说,一件hackie的事情似乎很奇怪:我手动调用$digest()。它是好吗?任何想法吗?

JS:

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?

但这样做正确吗?

1 个解决方案

#1


12  

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.

调用$digest并不容易——您的示例中的消息将被添加到keyup上的模型中,而且在某些东西告诉它之前,angle不会消化这些更改。实际上,它将在下一个按键上被简化,但是由于您需要在您的按键后执行$digest,所以您必须手动调用它。

#1


12  

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.

调用$digest并不容易——您的示例中的消息将被添加到keyup上的模型中,而且在某些东西告诉它之前,angle不会消化这些更改。实际上,它将在下一个按键上被简化,但是由于您需要在您的按键后执行$digest,所以您必须手动调用它。