<div 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}}">
</div>
<script src="angular.min.js"></script>
第二个文本框会自动套用第一个文本框的值,但是,一旦手动输入了第二个文本框,以后就不起作用了,用什么办法呢?
另外,第二个例子里,一旦select加了ng-model后,就多出了一项,什么原因?如何避免?
嗯嗯,我昨晚就看到这个问题了,我没有回答的原因是因为文档上就有答案。
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。
综上,希望对你有所帮助。