【问题标题】:Does my ng-model really need to have a dot to avoid child $scope problems?我的 ng-model 真的需要一个点来避免子 $scope 问题吗?
【发布时间】:2013-06-15 06:16:57
【问题描述】:

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

范围继承通常很简单,而且您通常甚至不需要知道它正在发生...直到您尝试将 2 路数据绑定(即,表单元素,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>

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

【问题讨论】:

    标签: angularjs angularjs-scope


    【解决方案1】:

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

    您决定为此使用指令:

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

    嗯,知道吗? &lt;tabs&gt; 有它自己的作用域,并且把你的控制器弄坏了!所以当你编辑时,Angular 会在 js 中做这样的事情:

    $scope.theText = element.val();
    

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

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

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

    【讨论】:

    • 好的,所以搞砸的先决条件似乎是有一个子范围也引用theText。对吗?
    • 修改它*。简单地引用它就可以了。
    • 所以在我的原始帖子示例中,我应该没问题,并且不会被搞砸,因为我的模板不包含任何引用 theText? 的子指令
    • 没错。点规则(恕我直言)仍然适用,因为您不知道将来是否要添加子模板。
    • 我打算为这个问题添加一个答案,但最后一条评论涵盖了我想要添加的内容——使用点规则未来证明您的设计。
    【解决方案2】:

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

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

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

    【讨论】:

    • 是的,我从理论上理解了这个问题,但我看不出它在实践中如何影响这个简单的例子。例如。 “如果 A 和 B 都依赖于这个属性”——那什么时候会是真的?一个建立在我的基础上的例子会很好。
    • 假设您有一个应用级控制器,并且您在其中有 ng-view,您可以根据路由加载单独的控制器。然后,您可能希望在切换路由后在主控制器上保留一些状态。这是一个例子。
    • 一些像 ng-include 这样的指令会创建自己的作用域。另一个可能出错的地方。
    • 所以在那个例子中,我必须有两条单独的路线,它们都想修改theText 才能发生这个问题?
    • 一个人修改就够了,如果两个人都需要看。
    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2015-09-26
    • 1970-01-01
    • 2019-11-24
    相关资源
    最近更新 更多