5

redactor (wysiwyg エディター) のディレクティブを作成しました。いくつかのハッキング後に機能しますが、正しい方法を見つけたいと思います。私にとっての主な課題は、ng-model と redactor jquery プラグインの間の双方向バインディングです。wysiwyg エディタから keyup と command イベントをリッスンし、モデルを更新します。また、リダクター エディターの外部からモデルの変更を監視して、それに応じてリダクター エディターを更新できるようにします。トリッキーな部分は次のとおりです。reactor エディターによって課された ng-model の変更 (バインディングの前半から) を無視するにはどうすればよいですか?

次のコードでは、リダクター エディターがモデルに更新した最後の値を記憶し、モデルの新しい値がその最後の値と等しい場合、モデルの変更を無視します。これがこれを達成する正しい方法であるかどうかは本当にわかりません。これは 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
4

1 に答える 1

0

Mark Rajcok が解決策を提供してくれました (ありがとう!) 秘訣は、$watch() ではなく ngModel.$render() を使用することです。

使用する

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
于 2013-03-11T18:23:29.473 に答える