title: Angular Directive - how to setup bi-directional binding with ng-model
body: <p>I wrote a directive for redactor (a wysiwyg editor). It works after some hacking but I would like find out the right way. The main challenge for me is the bi-directional binding between the ng-model and the redactor jquery plugin. I listen to keyup and command event from the wysiwyg editor and update the model. I also watch for model change from outside the redactor editor so that I can update the redactor editor accordingly. The tricky part is: How do I ignore the ng-model change imposed by the reactor editor (from the first half of the binding)?</p>
  
  <p>In the following code, it remembers the last value the redactor editor updates to the model and ignore model change if the new value of the model equals to that last value. I am really not sure if this is the right way to achieve this. It seems to me that this is a common problem with bi-directional binding in Angular and there must be a <strong><em>right</em></strong> way. Thanks!</p>
  
  <pre><code>&lt;textarea ui-redactor='{minHeight: 500}' ng-model='content'&gt;&lt;/textarea&gt;
  </code></pre>
  
  <p>directive.coffee (sorry for the coffeescript)</p>
  
  <pre><code>angular.module("ui.directives").directive "uiRedactor", -&gt;
  
    require: "ngModel"
    link: (scope, elm, attrs, ngModel) -&gt;
      redactor = null
      updatedVal = null
  
      updateModel = -&gt;
        ngModel.$setViewValue updatedVal = elm.val()
        scope.$apply()
  
      options =
        execCommandCallback: updateModel
        keydownCallback: updateModel
        keyupCallback: updateModel
  
      optionsInAttr = if attrs.uiRedactor then scope.$eval(attrs.uiRedactor) else {}
  
      angular.extend options, optionsInAttr
  
      setTimeout -&gt;
        redactor = elm.redactor options
  
      #watch external model change
      scope.$watch attrs.ngModel, (newVal) -&gt;
        if redactor? and updatedVal isnt newVal
          redactor.setCode(ngModel.$viewValue or '')
          updatedVal = newVal
  </code></pre>