AngularJS,通过引用更新子控制器视图中的ng-repeat

时间:2014-09-09 23:08:08

标签: javascript angularjs

我有一个子控制器,它引用了它的父级的值。

问题是子控制器视图中的 ng-repeat 在更新父控制器值时不会更新。< / p>

所以我的问题是:如果更新父控制器值而子元素值是参考值,那么如何更新子控制器ng-repeat?

儿童控制器:

angular.module('angularApp').controller('PostController', function ($scope) 
{
    $scope.mainController = $scope.$parent.getMainController();
    $scope.editController = $scope.$parent;
    $scope.posts = $scope.mainController.currentStation.posts;
    $scope.featuredAlbums = $scope.$parent.featuredAlbums;

    $scope.updatePost = function(postId){
        $scope.editController.updatePost(postId);
    };

    $scope.updateFeatured = function(featuredId){
        $scope.editController.updateFeatured(featuredId);
    };
});
子控制器

下的

ng-repeat

<div ng-controller="PostController" class="posts">
<div ng-repeat="featuredAlbum in featuredAlbums">

中断的示例:

http://plnkr.co/edit/GKjYAWEEWOrp84bwIIOt?p=info

**答案**

感谢快速响应人员,我意识到在控制器中创建的所有内容都是通过值而不是引用传递的,即使从父控制器引用的值也会重新创建为本地范围的控制器值。

那么解决方案呢?简单。

只需直接调用父级,而不是重新创建本地范围的变种

$scope.$parent.$someValue

3 个答案:

答案 0 :(得分:1)

我不确定我是否理解你的问题。所以我创建了一个包含两个控制器的plunker。在我看来,子值始终更新。您能告诉我们您的原始问题是如何相关的吗?

`http://plnkr.co/edit/9aHqdbbIe5aGJSuHogPA?p=preview`

答案 1 :(得分:1)

发生的情况是您在子范围内获取数据的新副本,而父范围未更新。

使其工作的最简单方法是不直接在父作用域上存储需要子控制器可访问的任何对象。您将获得更少的代码和更少的复杂性。

在您的情况下,在父母中有类似的内容:

$scope.media = {
    featuredAlbums : [ ... ],
    currentStation : {
        posts : {...}
    }
}
$scope.functions = {
    updatePost : function (pid) {
        // your function
    },
    updateFeatured : function (pid) {
        // your function
    }
}

并且在孩子中不要理会所有的继承,只是直接调用函数:

$scope.functions.updatedFeatured(featureID);
$scope.functions.updatePost(postId);

您的功能和数据所在的父控制器无关紧要,如果您附加到控制器的属性而不是控制器本身,它将找到它们。

看看这段视频,它更好地解释了它。

https://egghead.io/lessons/angularjs-the-dot

编辑

正如David Beech所指出的,不需要在属性中存储父作用域函数,因为该函数未被修改。但是,这种方法意味着简单规则,无需额外考虑哪些数据/函数是只读的,哪些是可写的。

答案 2 :(得分:1)

想象一下这个场景:

app.controller('ParentController', function($scope) {
   $scope.rawValue = 3;
   $scope.hiddenValue = false;
   $scope.objectValue = {
       name: 'David',
       age: 27
   };
   $scope.someFunction = function(input) {
       return input;
   }
});

app.controller('ChildController', function($scope) {
   $scope.hiddenValue = true;
   //Notice i don't need to wrap calls to parent functions or reassign parent data.
   //this is because the $scope object will automatically inherit from it's parent.
});


<div ng-controller="ParentController">
     {{ hiddenValue }} //false, remains false as setting only occured on child scope;
     {{ rawValue }} //3, remains 3 as setting will only occur on child scope;
     {{ objectValue.name }} // 'David' however will dynamically update with input below.

     <div ng-controller="ChildController">
         {{ hiddenValue }} //true because now it's scoped;
         <input type="button" ng-click="someFunction('hello')" value="calls function on parent scope" />
         <input type="text" ng-model="rawValue" /> //will initialise as 3 but as soon as updated it will be scoped on this scope.
         <input type="text" ng-model="objectValue.name" /> //will initialise as David and will correctly update parent scope as edited.
     </div>
</div>

那为什么会这样呢?

无论何时访问属性或功能,它都会自动向上移动$scope层次结构以查找值。无需明确指定$parent,因为这是javascript继承的工作方式。

但是,无论何时修改/设置某个值,它都会出现在最近的$scope上,并且是&#39;范围内的&#39;。在上面的示例中,hiddenValuerawValue会发生什么。但请注意,它在objectValue.name上按预期工作,这是因为为了设置name属性,您必须先获得&#39; objectValue。因此,javascript继承沿着作用域链向上移动以从父作用域获取objectValue,然后设置它的name属性。

两条准则:

  1. ng-model通常应使用&#39;。&#39;所以它迫使这个范围走。
  2. 使用$ parent通常是个坏兆头。如果使用正确,父属性应该已经可以通过当前的$ scope单独使用。