简体   繁体   English

ngRepeat不会更新阵列

[英]ngRepeat does not update the array

The Problem 问题

I have a ngMake() function which makes a request to makepost.php and using the user's input it adds a new "post" to the database. 我有一个ngMake()函数,该函数向makepost.php发出请求,并使用用户的输入将新的“ post”添加到数据库中。 This operation is successful, and I know this, because after I fill in the makepost.html form and I refresh the page, the newly created post is there. 该操作成功完成,我知道这一点,因为在我填写makepost.html表单并刷新页面后,新创建的帖子就在那里了。 I want it so that the page needn't be refreshed. 我想要它,因此无需刷新页面。 As I have gathered Angular's two-way data-binding should take care of this automatically, so maybe I have some problem with the $scope , I've been reading, but I guess because I am a beginner I don't really know what is causing the issue, or if I should create a new function which makes use of $scope.$watch() , I've sort-of tried $scope.$apply() . 当我收集了Angular的双向数据绑定后,该数据应该自动处理,所以也许我在$scope遇到了一些问题,但我一直在阅读,但是我想因为我是一个初学者,所以我真的不知道该怎么做。引起了这个问题,或者如果我应该创建一个使用$scope.$watch()的新函数,我已经尝试了$scope.$apply() I don't know, anything would be helpful, thank you. 我不知道,有什么会有所帮助的,谢谢。

Factory 'postFactory' 工厂'postFactory'

app.factory('postFactory', function($http) {
var postFactory = {
    async: function() {
        var promise = $http.get('server/blog/posts.php')
            .success(function(response) {
                return response;
            })
            .error(function(error, status) {
                $scope.response.error = { message: error, status: status };
                console.log($scope.response.error.status);
            });
        return promise;
    }
};
return postFactory;

}); });

Inside the blog.controller 在blog.controller内部

postFactory.async().then(function(response) {
    $scope.posts = response.data.Posts;
});

HTML 的HTML

<div ng-controller="BlogController as blog">
<div class="dont-break-out" ng-repeat="post in posts">
    <a href="#{{post.Slug}}">
        <hr>
        <h4>{{post.Title}}</h4>
        <div ng-bind-html="ngHTML((post.Content | limitTo : 125) + '..')"></div>
    </a>
    <footer class="text-right"> On {{post.DateSubmited}}
        <br> By {{post.UserName}}
    </footer>
</div>
<hr>

The entire project on GitHub GitHub上的整个项目

are you sure you are returning the posts list inside a data property?. 您确定要返回数据属性内的帖子列表吗? i read your code in posts.php and i do find an object that holds the list of posts, but it is returned just like that 我在posts.php中阅读了您的代码,但确实找到了一个保存帖子列表的对象,但它却像这样返回

echo json_encode(array(
        'Posts' => $rows
     ));

and in your js code you are requesting 并在您的js代码中请求

$scope.posts = response.data.Posts;

maybe it is that you are confused about the kind of promise you are handling at that moment, when you use the $http method it does return a data property, but a normal promise doesn't do that, you access directly the data in your object like this: 也许是因为您对当时正在处理的承诺感到困惑,当您使用$ http方法时,它确实返回了data属性,但是普通的Promise却没有这样做,您可以直接访问自己的数据。像这样的对象:

$scope.posts = response.Posts;

Your ng-repeat isn't updating because it's always pointing at the original posts array, even when you've gotten a new one. 您的ng-repeat不会更新,因为它始终指向原始的posts数组,即使您有一个新的数组也是如此。

What happens is that on your initial page load, you get a brand new array (let's call it array1 ) from the server, and you give that array to both your $scope your ng-repeat. 发生的情况是,在初始页面加载时,您从服务器获得了一个全新的数组(我们称其为array1 ),并将该数组提供给$scope ng-repeat。 When you make a new post and call async() a second time, you get back another brand new array ( array2 ), and you give it to your $scope , but not ng-repeat. 当您发布新帖子并再次调用async()时,您会得到另一个全新的数组( array2 ),并将其提供给$scope ,而不是 ng-repeat。 It's already got its array; 它已经有了它的数组; it's happy. 很高兴 It doesn't know or care what $scope thinks the new array is--they can point to completely different lists. 它不知道也不关心$scope认为新数组是什么,它们可以指向完全不同的列表。

This is a subtle problem you can see a lot with Angular views, and it's one of the reasons you will often see people recommend that you never reference anything in the view without accessing it as a property of something else. 这是一个微妙的问题,您可以在Angular视图中看到很多,这也是您经常看到人们建议不要在未将视图作为其他属性访问的情况下引用该视图中任何内容的原因之一。 That way, when you change the property on the container object, ng-repeat will see the change because it's watching the container object's property rather than just holding its own reference with no connection to anything else. 这样,当您更改容器对象的属性时, ng-repeat将看到更改,因为它正在监视容器对象的属性,而不是仅保留其自己的引用而没有任何其他连接。

To solve your issue, you can create a new container object (let's call it data ), and place the posts property on it instead. 为了解决您的问题,您可以创建一个新的容器对象(我们称其为data ),然后在其上放置posts属性。

So inside your blogController, you would start by declaring 因此,在您的blogController中,您首先要声明

$scope.data = {};

and then your calls to async() would look like 然后您对async()调用看起来像

postFactory.async().then(function(response) {
    $scope.data.posts = response.data.Posts;
});

and your ng-repeat would look like 和您的ng-repeat看起来像

ng-repeat="post in data.posts"

The end result is that ng-repeat will hold onto the reference for data and never let it go, and it will automatically notice and update every time the posts property is changed. 最终结果是ng-repeat将保留data的引用,并且永不让它消失,并且每次posts属性更改时,它将自动注意到和更新。


As an aside, you don't need the $scope.apply() calls in any of your callback handlers. 顺便说一句,您不需要任何回调处理程序中的$ scope.apply()调用。 Angular calls $scope.apply() at the completion of every $http request. Angular在每个$ http请求完成时调用$ scope.apply()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM