【问题标题】:Angular Directive - how to setup bi-directional binding with ng-modelAngular Directive - 如何使用 ng-model 设置双向绑定
【发布时间】:2013-03-11 15:48:55
【问题描述】:

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

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

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

directive.coffee(对不起,咖啡脚本)

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

【问题讨论】:

  • 你是否尝试过实现 ngModel.$render() 而不是 $watch()?似乎 $render() 只有在 Angular 内部的某些东西改变了模型时才会被调用。在这个fiddle 中,$render() 仅在我单击链接时被调用(它以编程方式更改模型)。 (因为我没有编辑许可证,所以无法测试。)
  • 马克,这对我有用。非常感谢!
  • 太好了,很高兴它成功了,感谢您告诉我们。
  • 我正在使用这个指令并且对绑定很有用,除了一个问题。最后一次更改(无论是按键/粘贴还是其他任何内容)都不会绑定,直到另一个按键。所以总是落后一步。 (所有回调都正确执行)
  • 是的,这不再起作用了。小提琴不起作用

标签: javascript angularjs angularjs-directive


【解决方案1】:

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

【讨论】:

  • 模板中定义的ng-model没有使用这个指令更新?知道为什么吗?
猜你喜欢
  • 1970-01-01
  • 2017-01-11
  • 2018-05-14
  • 1970-01-01
  • 2017-04-25
  • 2019-02-21
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多