24

根据https://github.com/angular/angular.js/wiki/Understanding-Scopes,尝试将数据绑定到附加到您的原语是一个问题$scope

范围继承通常很简单,而且您通常甚至不需要知道它正在发生...直到您尝试将 2 路数据绑定(即表单元素、ng-model)到一个基元(例如,数字、字符串、 boolean) 在子范围内的父范围上定义。它不像大多数人期望的那样工作。

建议是

通过遵循始终使用“.”的“最佳实践”,可以轻松避免原语的这个问题。在你的 ng 模型中


现在,我有一个非常简单的设置,它违反了这些规则:

HTML:

<input type="text" ng-model="theText" />
<button ng-disabled="shouldDisable()">Button</button>

JS:

function MyController($scope) {
    $scope.theText = "";
    $scope.shouldDisable = function () {
         return $scope.theText.length >= 2;
    };
}

这真的很糟糕吗?当我开始尝试使用子示波器时,这会以某种可怕的方式把我搞砸吗?


我是否需要将其更改为类似

function MyController($scope) {
    $scope.theText = { value: "" };
    $scope.shouldDisable = function () {
         return $scope.theText.value.length >= 2;
    };
}

<input type="text" ng-model="theText.value" />
<button ng-disabled="shouldDisable()">Button</button>

以便我遵循最佳做法?你能给我什么具体的例子,后者将使我免于前者会出现的可怕后果?

4

2 回答 2

19

很多东西都引入了新的作用域。假设在您的控制器中,您实际上想要添加选项卡:第一个选项卡是实际渲染,第二个选项卡是表单(以便您进行实时预览)。

您决定为此使用指令:

<tabs>
  <tab name="view">
    <pre>{{theText|formatInSomeWay}}</pre>
  </tab>
  <tab name="edit" focus="true">
    <input type="text" ng-model="theText" />
  </tab>
</tabs>

嗯,知道吗?<tabs>有自己的范围,并打破了你的控制器!所以当你编辑时,angular 会在 js 中做这样的事情:

$scope.theText = element.val();

它不会遍历原型链来尝试设置theText父母。

编辑:为了清楚起见,我只使用“标签”作为示例。当我说“很多东西引入了一个新的范围”时,我的意思是:ng-include、ng-view、ng-switch、ng-controller(当然)等。

所以:目前可能不需要,因为您在该视图中还没有子范围,但您不知道是否要添加子模板,这可能最终会修改theText自己,导致问题。为了将来证明您的设计,请始终遵循规则,然后您就不会感到惊讶了;)。

于 2013-06-19T08:40:19.837 回答
6

假设您有作用域 M、A 和 B,其中 M 是 A 和 B 的父级。

如果 (A,B) 之一尝试写入 M 的作用域,它将仅适用于非原始类型。原因是非原始类型是通过引用传递的

另一方面,原始类型不是,因此尝试theText在 M 的作用域上写入将分别在 A 或 B 的作用域上创建一个同名的新属性,而不是写入 M。如果 A 和 B 都依赖于该属性,错误将会发生,因为他们中的任何一个都不会知道另一个人在做什么。

于 2013-06-18T21:18:40.810 回答