search

Home  >  Q&A  >  body text

javascript - 第二个输入框如何才能无条件的使用第一个输入框的值?



<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后,就多出了一项,什么原因?如何避免?

巴扎黑巴扎黑2901 days ago395

reply all(2)I'll reply

  • 迷茫

    迷茫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 属性的值。这一点比较繁琐,让我试着说明(不一定正确,只是粗读源码后的推测):

    1. ngModelController 有一个属性叫 $viewValue,它才是真正保存和更新视图里我们看到的值。
    2. ngModelController 有自己的逻辑来根据获取到的 $viewValue 来维护自身的 model
    3. 原谅我没时间去细细阅读源代码,我对 Angular 没那么大的兴趣,所以我能做出最靠谱的猜想就是 $viewValue 的优先级要比我们直接声明的 value 高。而 $viewValue 自身值的获取有时候是来自于 value(比如你的例子里:value={{aaa}}),但有的时候(应该是 ngModelController 里的 model 不为空的时候,也就是你手动更改了第二个 input 的值之后)就不会让 value 属性的值来覆盖它了。
    4. 事实上这一点很好理解,源自于 directive 要维护自身作用域的独立性原则。如果 $viewValue 是空的(初始状态),那么当然有必要去获取我们绑定在 value 属性里的值,但如果不是(我们手动更改了),那就不要让 value 属性的值去覆盖它(因为这个值很可能是来自其他作用域的,一般我们更希望保证 ng.input 自身作用域的独立性。

    以上所说是 Angular 的默认抉择,很显然它无法满足你的需求(坦白说你的需求很“特异”,如果我的应用里出现了这种情况,我更倾向于重新思考一下这部分的设计,而不是硬生生的整两个 input 上去,因为这很容易让用户感到困惑)。

    如果我们非要实现这一点,那就要自己去处理这个逻辑,简单的思路就是,我们要用两个属性(model)来分别绑定 A、B(代表俩 ng.input),然后编写合适的逻辑来同步 A 和 B 的变化:

    1. A 变,B 就变,而且是完全覆盖 B
    2. B 变,A 不管。

    当然了,这个逻辑是要写在 controller 里了。Actually,如果非要实现这样的东西,我更愿意写一个新的 directive。

    综上,希望对你有所帮助。

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 14:37:25

    {{aaa}}的意思不就是输出model叫aaa的值么?

    第二个没有复现,我测试看到就2个选项

    第二个看到了,因为model没有初始值

    reply
    0
  • Cancelreply