ngModel - 如何在不同的浏览器中处理它的不同行为?

akn*_*akn 14 javascript jquery jquery-ui angularjs angular-ngmodel

我正在尝试处理ngModel不同浏览器中的不同行为.

我的指令包装jqueryUI自动完成,并在其select调用的事件上ngModel.$setViewValue(selectedItem.id).自动完成功能允许用户通过鼠标单击或按enter键盘选择项目.

如果建议的项目是:

{
  "name": "Apple",
  "id": "1000"
}
Run Code Online (Sandbox Code Playgroud)

我希望在选择之后,ngModel值将被选为项目id- 1000.

  • 在Chrome中它的工作原理确定-它集$viewValue$modelValue正确的($modelValue=1000).

  • 在Firefox中它将模型设置为Chrome($modelValue=1000),但是当我点击其他地方时 - 使模糊(然后浏览器可能触发change事件),模型更改并且它变得与可见输入值($modelValue='Apple')相同.

  • 在IE 11中,只有当我通过鼠标单击选择项目时,它才会设置模型正确.如果按下选择它enter,模型将变为可见输入值($modelValue='Apple')

这是plunkr:http://plnkr.co/edit/o2Jkgprf8EakGqnpu22Y? p =preview

我想在每个浏览器中达到相同的行为.如何处理那些问题?

akn*_*akn 1

好吧,我想我已经做到了。该解决方案基于Yoshi 的评论,它使用本地模型来保留选定的数据。

当用户选择某项时,本地模型将设置为已选择Object,并$viewValue设置为所选项目的文本值。然后解析器将id本地模型的属性设置为$modelValue

select: function(event, ui) {
  if(ui.item && ui.item.data){
    model = ui.item.data
    ngModel.$setViewValue(model.name);
    scope.$apply();
  }
}

ngModel.$parsers.push(function(value) {
  if(_.isObject(model) && value!==model.name){
    model = value;
    return model;
  }
  return model.id;
});
Run Code Online (Sandbox Code Playgroud)

解析器函数还做了一件重要的事情。因为它在用户键入内容或事件时运行change(这就是 Firefox 中的问题!),所以它会检查该值是否与当前本地模型的文本值相同,如果不是,则将本地模型更改为该值。这意味着如果解析器函数由事件值运行,则change值将与文本值相同,因此$modelValue不会更改,但如果用户键入某些内容,则模型将更新为键入的值(变为String)。

验证器函数检查本地模型是否为Object. 如果不是,则意味着该字段无效,因此默认情况下它会$modelValue消失。

这是 plunkr: http://plnkr.co/edit/2ZkXFvgLIwDljfJoyeJ1 ?p=preview

(在格式化程序函数中,我返回所发生的内容,所以$viewValue暂时是一个Object,但然后在$render方法中我调用$setViewValue设置$viewValue$modelValue正确,所以它变成了String。我听说$setViewValue不应该在$render方法中运行,但我没有看到其他方法来设置正确的$modelValue时间有东西来自外部)。