首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >angular-bootstrap (Tab):数据绑定只起单向作用

angular-bootstrap (Tab):数据绑定只起单向作用
EN

Stack Overflow用户
提问于 2013-02-19 23:29:51
回答 3查看 4.3K关注 0票数 11

我准备了一把小提琴,并把它压缩到最低限度:

http://jsfiddle.net/lpeterse/NdhjD/4/

代码语言:javascript
复制
<script type="text/javascript">
    angular.module('app', ['ui.bootstrap']);

    function Ctrl($scope) {
      $scope.foo = "42";
}
</script>


<div ng-app="app" ng-controller="Ctrl">
    1: {{foo}}<br />
    2: <input ng-model="foo" />
    <tabs>
        <pane heading="tab">
            3: {{foo}}<br />
            4: <input ng-model="foo" />
        </pane>
    </tabs>    
</div>

在开始时,所有视图都引用模型Ctrl.foo

如果您在input 2:中更改了某些内容,它会正确地更新模型,并且此更改将传播到所有视图。

在input 4:中更改某些内容只会影响包含在同一窗格中的视图。它的行为就像作用域以某种方式派生出来的。之后,来自2:的更改将不再反映在选项卡中。

我阅读了有关指令、作用域和转换的angular文档,但找不到对这种不受欢迎的行为的解释。

如有提示,我将不胜感激:-)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-20 00:18:07

这个问题与编辑原语时在ng-repeat中的问题相同- <pane>指令创建了一个继承自父对象的新作用域。

现在,给定Javascript继承的工作方式,<pane>指令有它自己的foo字符串原语副本,当您编辑它时,您只能在窗格的子作用域上编辑它。

一个简单的解决方案是将foo放在父Ctrl上的一个对象中:

代码语言:javascript
复制
function Ctrl($scope) {
  $scope.data = { foo: 42 };
}

然后,您可以在HTML中执行以下操作:

代码语言:javascript
复制
<tabs><pane><input ng-model="data.foo"></pane></tabs>

为什么它要与对象一起工作?因为当<pane>继承父对象的作用域时,它对data的引用将引用内存中与父Ctrl上相同的对象。像字符串和数字这样的原语是在继承中复制的,而对象只是创建一个指向同一对象的新指针。

<pane>的新作用域继承了foo字符串原语作为foo的新副本,当被编辑时不会在父Ctrl上改变。<pane>的新作用域将继承一个像data这样的对象作为对同一对象的引用,并且当在<pane>作用域上编辑时,相同的对象将在父作用域上被引用。

有用的文章:https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

票数 12
EN

Stack Overflow用户

发布于 2013-03-01 01:27:29

<tabs><pane>指令分别创建一个新的转换子作用域(因为它们都有transclude: true,)和一个隔离子作用域,前者通常从父作用域继承,后者不典型地从父作用域继承。<pane>中的<input...>使用被转换的子范围。

当第一次呈现<pane>中的input时,会用$scope.foo的值填充它。正常的JavaScript原型继承在这里开始发挥作用……最初,foo是在转换子作用域上定义的而不是(原型继承不复制原语),因此JavaScript遵循原型链并查看父对象/$ scope,并在那里找到它。将42放入文本框中。被转移的子作用域未受影响/更改(尚未)。

如果编辑第一个文本框,则会更新第二个文本框,因为JavaScript仍在使用原型继承来查找$scope.foo的值。

如果您编辑第二个文本框,也就是429,Angular会将值写入$scope.foo,但请注意,$scope是转换子范围。因为foo是一个原语,所以它在该子作用域上创建了一个新属性--无论好坏,这就是JavaScript的工作方式。此新属性将隐藏/隐藏同名的父作用域属性。原型继承在这里不起作用。(安迪在他的帖子(也是on SO)中提到的文章也详细解释了这一点,并附有图片。)由于转换子作用域现在具有foo属性,因此它现在将使用该本地属性进行读写,因此它看起来与父作用域“断开连接”。

使用对象(而不是原语)解决了这个问题,因为原型继承总是起作用的。转换子作用域获取对父作用域中的对象的引用。写入data.foo将写入父对象上的data对象,而不是被转换的子作用域。

票数 4
EN

Stack Overflow用户

发布于 2013-02-20 00:10:43

问题出在tabs指令中。我想是在line 1044 of ui-bootstrap-tpls-0.1.0.js上。

如果您将scope: {}更改为scope: { foo: '='},它将为您提供双向数据绑定。

来自Angular Docs

= or =attr -在本地作用域属性和通过attr属性的值定义的name的父作用域属性之间设置双向绑定。如果未指定attr名称,则假定属性名称与本地名称相同。给定和小部件范围的定义:{ localModel:'=myAttr‘},然后小部件范围属性localModel将反映父范围上的parentModel的值。对parentModel的任何更改都将反映在localModel中,而对localModel的任何更改都将反映在parentModel中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14961155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档