Angular Directive - 如何使用ng-model设置双向绑定

时间:2013-03-11 15:48:55

标签: javascript angularjs angularjs-directive

我为redactor(一个所见即所得的编辑器)编写了一个指令。它在一些黑客攻击后起作用,但我想找到正确的方法。对我来说,主要的挑战是ng-model和redactor jquery插件之间的双向绑定。我从wysiwyg编辑器中听取keyup和命令事件并更新模型。我还从redactor编辑器外部观察模型更改,以便我可以相应地更新redactor编辑器。棘手的部分是:如何忽略反应器编辑器强加的ng模型变化(从绑定的前半部分开始)?

在下面的代码中,它会记住redactor编辑器更新到模型的最后一个值,如果模型的新值等于最后一个值,则忽略模型更改。我真的不确定这是否是实现这一目标的正确方法。在我看来,这是Angular中双向绑定的常见问题,必须有 正确 方式。谢谢!

<textarea ui-redactor='{minHeight: 500}' ng-model='content'></textarea>

directive.coffee(对不起coffeescript)

angular.module("ui.directives").directive "uiRedactor", ->

  require: "ngModel"
  link: (scope, elm, attrs, ngModel) ->
    redactor = null
    updatedVal = null

    updateModel = ->
      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 ->
      redactor = elm.redactor options

    #watch external model change
    scope.$watch attrs.ngModel, (newVal) ->
      if redactor? and updatedVal isnt newVal
        redactor.setCode(ngModel.$viewValue or '')
        updatedVal = newVal

1 个答案:

答案 0 :(得分:0)

Mark Rajcok给出了解决方案(谢谢!)诀窍是使用ngModel。$ render()而不是$ watch()。

使用

ngModel.$render = ->
  redactor?.setCode(ngModel.$viewValue or '')

而不是

scope.$watch attrs.ngModel, (newVal) ->
  if redactor? and updatedVal isnt newVal
    redactor.setCode(ngModel.$viewValue or '')
    updatedVal = newVal