<p ng-app>
<!-- 文本框的例子:第二个文本框手工输入后即失效? -->
<input ng-model="aaa">
<input value="{{aaa}}">
<!-- 选择框的例子: 为什么下拉列表里多了一项? -->
<select ng-model="bbb">
<option value="1">111</option>
<option value="2">222</option>
</select>
<input value="{{bbb}}">
</p>
<script src="angular.min.js"></script>
第二个文本框会自动套用第一个文本框的值,但是,一旦手动输入了第二个文本框,以后就不起作用了,用什么办法呢?
另外,第二个例子里,一旦select加了ng-model后,就多出了一项,什么原因?如何避免?
迷茫2017-04-10 14:37:25
嗯嗯,我昨晚就看到这个问题了,我没有回答的原因是因为文档上就有答案。
http://jsbin.com/buqeva/1/edit
看看这个例子,然后去看看 ng.input
的文档,一旦你理解 Angular.js 里的 input
不是常规 HTML 里的 input
(它是个 directive),你的问题就会迎刃而解。
第二个例子也是类似的道理,答案都在文档上。
出现你描述的问题的原因稍微有些复杂,首先我们得说一说 ng.input
和 <input>
的区别。
对于普通的 <input>
,我们看到的值就是 value
属性的值,这也是为什么你认为只要有 value={{aaa}}
<input>
就能响应 aaa
的变化的原因——但是事实并非如此单纯。
ng.input
本身是一个 directive,它自身带有一个 ngModelController
,也就是说它有它自己的 model
,当然我们也可以使用 ng-model
来指定我们希望的 model
。这就是为什么如果两个 ng.input
指向同一个 model
,它们就会相互响应对方的变化——双向绑定,right?
然而还有一个细节很容易让人忽略,使用 ng.input
,你看到的值不一定是你认为来自 value
属性的值。这一点比较繁琐,让我试着说明(不一定正确,只是粗读源码后的推测):
ngModelController
有一个属性叫 $viewValue
,它才是真正保存和更新视图里我们看到的值。ngModelController
有自己的逻辑来根据获取到的 $viewValue
来维护自身的 model
$viewValue
的优先级要比我们直接声明的 value
高。而 $viewValue
自身值的获取有时候是来自于 value
(比如你的例子里:value={{aaa}}
),但有的时候(应该是 ngModelController
里的 model 不为空的时候,也就是你手动更改了第二个 input 的值之后)就不会让 value
属性的值来覆盖它了。$viewValue
是空的(初始状态),那么当然有必要去获取我们绑定在 value
属性里的值,但如果不是(我们手动更改了),那就不要让 value
属性的值去覆盖它(因为这个值很可能是来自其他作用域的,一般我们更希望保证 ng.input
自身作用域的独立性。以上所说是 Angular 的默认抉择,很显然它无法满足你的需求(坦白说你的需求很“特异”,如果我的应用里出现了这种情况,我更倾向于重新思考一下这部分的设计,而不是硬生生的整两个 input
上去,因为这很容易让用户感到困惑)。
如果我们非要实现这一点,那就要自己去处理这个逻辑,简单的思路就是,我们要用两个属性(model)来分别绑定 A、B(代表俩 ng.input
),然后编写合适的逻辑来同步 A 和 B 的变化:
当然了,这个逻辑是要写在 controller 里了。Actually,如果非要实现这样的东西,我更愿意写一个新的 directive。
综上,希望对你有所帮助。