我的ng模型真的需要一个点来避免孩子的范围问题吗?

时间:2013-06-18 21:06:55

标签: angularjs angularjs-scope

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

  

范围继承通常很简单,你甚至不需要知道它正在发生......直到你尝试双向数据绑定(即表单元素,ng-model)到一个原语(例如,数字) ,string,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>

让我遵循最佳做法?你可以给我一个具体的例子,后者会让我免受前者可能产生的一些可怕后果的影响吗?

2 个答案:

答案 0 :(得分:19)

lot 的东西引入了新的范围。让我们说在你的控制器中,你实际上想要添加标签:第一个标签是实际渲染,第二个标签是表格(这样你就可以实时预览)。

您决定使用指令:

<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

编辑:为了清楚起见,我只是以“标签”为例。当我说“A lot 的东西引入了新的范围”时,我的意思是:ng-include,ng-view,ng-switch,ng-controller(当然)等等。

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

答案 1 :(得分:5)

假设您有范围M,A和B,其中M是A和B的父级。

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

另一方面,

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