如何在 AngularJS 应用中实现视图刷新而不刷新页面

4

我有一个简单的应用程序,列出联系人报告,在其中我制作了一个列表视图,从Mongolab获取数据。

我还制作了一个输入表单,当提交时在列表中创建新的联系人报告

我在控制器中使用的函数是从Angular官网的示例模拟的:

app.factory('Contact',function($mongolabResource){
    return $mongolabResource('contacts');
});

function ContactCreateCtrl($scope,$location,Contact) {
Contact.save(contact,function(){
        $location.path('/');
    });
};

$location.path()是重新加载页面的回调函数。

当数据提交成功(.save()成功)后,如何重写代码以使视图重新加载而无需重新加载页面?

我尝试删除并重新定义数组,但似乎不起作用:

Contact.save(contact,function(){
        delete $scope.contacts;
        $scope.contacts = Contact.query();
    });

我希望在删除功能上也能实现它。有人能指点我学习的地方吗?

非常感谢任何帮助


为什么需要重新加载视图? - Josh David Miller
所以我的列表显示了新添加的项目,现在它通过执行 $location.path() 来实现;如果我删除它,列表就不会更新,但是当我手动重新加载浏览器时,它会显示新项目。 - George Ananda Eman
我只是想要一个更流畅的应用体验,不需要页面重新加载。 - George Ananda Eman
视图重新加载不应该是必要的,因为绑定确保更新发生。你能在Plunker或jsFiddle上添加一个简单的例子吗? - Josh David Miller
我刚刚弄明白了这个问题,感谢您的见解,它在jsfiddle.net/Y223F上。 我刚刚发现我可以使用.push将数据添加到数组中,但这是最佳实践吗?我的意思是它正在向作用域中添加数据,但它并没有直接从数据库中提取数据,虽然它是相同的数据。我在想这会不会导致不一致? - George Ananda Eman
显示剩余2条评论
3个回答

9

好的,我已经更新了你的代码片段,从数据库中获取值:http://jsfiddle.net/joshdmiller/Y223F/2/

app.controller( 'MainCtrl', function ( $scope,Contact ) {
  $scope.updateContacts = function () {
    Contact.query( function( data ) {
      $scope.contacts = data;
    });
  };

  $scope.save = function( newContact ) {
    Contact.save( newContact, function() {
      $scope.updateContacts();
    });
  };

  // The initial data load
  $scope.updateContacts();  
});

需要注意两点:

(1) 我将您的Mongo查询移入一个函数中,以便在创建新记录时可以再次调用;

(2) $mongolabResource期望在成功执行时执行回调;您的应用程序闪烁是因为您没有提供回调。换句话说,从您调用查询到获取完成的时间内,您的列表为空。我们希望它只在获得新数据时才发生变化。我也对此进行了更改。

在手动添加项目或从数据库中获取项目方面,最佳实践基于用例,并且存在权衡。但对于这样的小数据,只需从数据库中获取即可。


啊,我明白了,没想到把它做成一个函数。谢谢 Josh。 - George Ananda Eman
@MarkRajcok 我知道这个方法是有效的,但正如我所说,它会导致闪烁问题。这里有一个相同的示例,移除了回调函数并直接赋值:http://jsfiddle.net/joshdmiller/Y223F/3/。直接赋值可能在初始检索时很有用,但在此之后它会降低用户体验。 - Josh David Miller
抱歉 @Josh,我没有仔细阅读你的答案。在你回复之前,我已经删除了我的评论。你的确做得更好(+1)。 - Mark Rajcok
1
此外,如果你对MongoLab和AngularJS感兴趣,你可能想要检查一个功能完整的$http,类似于MongoLab的适配器:https://github.com/pkozlowski-opensource/angularjs-mongolab-promise。这里有演示:http://embed.plnkr.co/Y8sg4V/preview - pkozlowski.opensource
1
一个非常小的技巧是在客户端将联系人添加到集合中,然后发出请求到服务器并在成功后更新联系人。这将使用户界面更加响应 - 我们假装在实际添加之前已经添加了联系人。 - Valentyn Shybanov
显示剩余3条评论

0

已经让它工作了,但是还不确定如何将其推入范围内的数组中,如果我们能够从数据库中获取数据会更好。

function ContactCreateCtrl($scope,$location,Contact) {
    Contact.save(contact,function(){
    $scope.contacts.push(contact);
});

还需要数据库自动生成的 _id 对象,以供链接使用。但是这种方法并没有给我 _id,有什么见解吗?


0
我分享了如何使用 Firebase 认证服务退出后清除视图中的数据的答案。在退出方法中调用 $scope.currentUser = null; 后,数据仍然存在。必须重新加载才能看到数据更改。不是最佳用户体验。
$scope.getCurrentUser = function() {
        firebase.auth().onAuthStateChanged(function(user) {
            if (user) {
                // User is signed in.
                $scope.currentUser = user;
            } else {
                // No user is signed in.
                $scope.currentUser = null;
                console.log('user not signed in.');
            }
        });
    }

$scope.getCurrentUser();


$scope.signout = function() {
        firebase.auth().signOut().then(function() {
          // Sign-out successful.
          console.log('signed out success');
          $scope.getCurrentUser();
        }, function(error) {
          // An error happened.
          console.log(error);
        });

    } 

因此,调用getUserData方法并在那里将currentUser = null更新了视图而无需重新加载。这是一个使用Firebase的示例,但通过进行一些调整,它可能适用于您清除视图中数据而不需要完全重新加载页面的需求。Firebase在这里承担了清除用户对象的重任,但在我的getCurrentUser方法中再次检查是否仍有用户,如果没有,则在不重新加载视图的情况下从$scope中清除它,我的视图不会关心。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接