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

AngularJS, updating ng-repeat within a child controller view by reference

本文关键字:视图 ng repeat 控制器 引用 更新 AngularJS      更新时间:2023-09-26

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

问题是子控制器视图中的ng repeat在更新父控制器值时不会得到更新。

所以我的问题是:当通过引用更新子控制器值时,如何更新子控制器ng重复?

子控制器:

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在子控制器下重复

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

中断示例:

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

**回答**

感谢快速响应的家伙,我意识到在控制器中创建的所有东西都是通过值而不是引用传递的,甚至从父控制器引用的值也被重新创建为本地范围的控制器值。

那么解决方案呢?易于理解的

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

$scope.$parent.$someValue

想象一下场景:

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上,并被"定域"。这就是上面例子中CCD_ 4和CCD_。但是请注意,它在objectValue.name上的工作与预期的一样,这是因为为了设置name属性,必须首先"获取"objectValue。因此,javascript继承沿着作用域链上行,从父作用域获取objectValue,然后设置其name属性。

两个指南:

  1. ng模型通常应使用"."从而迫使该示波器行走
  2. 使用$parent通常是一个坏兆头。如果使用正确,父属性应该已经可以单独通过当前的$scope使用

我不确定我是否正确理解你的问题。所以我创建了一个包含两个控制器的plunker。在我看来,孩子的价值观总是更新的。你能告诉我们你最初的问题是如何关联的吗?

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

发生的情况是,您在子作用域中获得了数据的新副本,而父作用域没有更新。

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

在你的情况下,在父母身上有这样的东西:

$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所指出的,没有必要将父作用域函数存储在属性中,因为该函数没有被修改。然而,这种方法是一种简单规则,它将在不考虑哪些数据/函数是只读的和哪些是可写的情况下工作。