【问题标题】:Behavior of assignment expression invoked by ng-click within ng-repeatng-repeat 中 ng-click 调用的赋值表达式的行为
【发布时间】:2013-03-01 13:36:02
【问题描述】:

我正在尝试使用附加到 <p>ng-click 更新我的模型。

我对@9​​87654324@ 的赋值表达式 之外,或者在ng-repeat内部 调用范围方法没有任何问题。但是,如果我在ng-repeat 中使用inside 赋值,它似乎被忽略了。我在 Firefox 控制台中没有看到任何消息报告,但没有尝试设置断点以查看事件是否被触发。

<!DOCTYPE html>
<html>
<head>
    <title>Test of ng-click</title>
    <script type='text/javascript' src='http://code.angularjs.org/1.1.1/angular.js'></script>
    <script type='text/javascript'>//<![CDATA[ 

        function MyCtrl($scope) {
            $scope.selected = "";
            $scope.defaultValue = "test";
            $scope.values = ["foo", "bar", "baz"];

            $scope.doSelect = function(val) {
                $scope.selected = val;
            }
        }
        //]]>  

    </script>
</head>

<body ng-app>
    <div ng-controller='MyCtrl'>
        <p>Selected = {{selected}}</p>
        <hr/>
        <p ng-click='selected = defaultValue'>Click me</p>
        <hr/>
        <p ng-repeat='value in values' ng-click='selected = value'>{{value}}</p>
        <hr/>
        <p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p>
    </div>
</body>
</html>

Fiddle 是 here,如果您愿意的话(以及几个早期的变体)。

【问题讨论】:

    标签: angularjs angularjs-scope


    【解决方案1】:

    指令 ngRepeat 为每次迭代创建一个新作用域,因此您需要在父作用域中引用您的变量。

    使用$parent.selected = value,如:

    <p ng-repeat='value in values' ng-click='$parent.selected = value'>{{value}}</p>
    

    注意:函数调用由于原型继承而传播。

    如果您想了解更多信息:The Nuances of Scope Prototypal Inheritance

    【讨论】:

    • 天啊!我知道这一定很简单。
    • +1。尽管 $parent 会起作用,但推荐使用模型的对象(有关更多详细信息,请参阅我的答案)。
    【解决方案2】:

    正如@Stewie 提到的,$parent 是解决此问题的一种方法。但是,推荐的 (by the Angular team) 解决方案是不在 $scope 上定义原始属性。相反, $scope 应该引用您的模型。使用引用也可以避免这个问题(因为不会在隐藏/隐藏同名父作用域属性的子作用域上创建原始属性),并且您不必记住何时使用 $parent:

    HTML:

    <p>Selected = {{model.selected}}</p>
    <hr/>
    <p ng-click='model.selected = defaultValue'>Click me</p>
    <hr/>
    <p ng-repeat='value in values' ng-click='model.selected = value'>{{value}}</p>
    <hr/>
    <p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p>
    

    JavaScript:

    $scope.model = { selected: ""};
    ...
    $scope.doSelect = function (val) {
       $scope.model.selected = val;
    }
    

    Fiddle.

    我最近更新了@Stewie 提到的 wiki 页面,以始终推荐这种方法。

    【讨论】:

    • +1 同意。使用 $parent 似乎总是有点 hackish,即使最终结果是一样的。我什至不使用它。猜猜我今天有点懒得解释'.'。此外,+1 用于更新 wiki。
    • 不得不说,我认为创建一个特殊的“模型”对象更像是一种 hack。并且更有可能导致复杂页面中的错误(如果没有其他原因,可能是拼写错误)。就个人而言,我认为函数是模型更新的最佳解决方案(也适用于ng-show 等表达式)。
    • @kdgregory “$scope 的目的是引用模型,而不是成为模型”(来自 Angular 团队视频马克提到的)。您可以使用任何您想要的 javascript 对象作为模型,然后从您的范围链接它。
    • 我迟到了三年多,但我觉得范围和模型之间的区别非常好。对于非常简单的用例,您可能希望将范围用作模型,但在实际应用程序中,将它们明确分开非常有用。
    猜你喜欢
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多