【问题标题】:How to change view asynchronously in Angular JS (from Lawnchair JS)?如何在Angular JS(来自Lawnchair JS)中异步更改视图?
【发布时间】:2013-01-31 10:26:01
【问题描述】:

我有一个相当简单的 2 页网络应用程序。使用 Angular 和 Lawnchair。我有一个登录页面,在用户通过身份验证并提取相关数据之前,我不希望从该页面更改屏幕/视图。此外,这是一个移动应用程序。因此用户可能只需要重新进行身份验证并从浏览器加载他们的数据。

<!DOCTYPE html>
<html xmlns:ng="http://angularjs.org" ng:app="AppMod">
<head>
...
</head>
<body ng:controller="AppCtrl">
    <ng:view></ng:view>
    ...
</body>
</html>

当我在没有适配器的情况下使用 Lawnchair 时,Angular 会很好地更改视图,并且 Lawnchair 将数据保存在浏览器中,但不会保存到像 WebSQL 或 IndexedDB 这样的永久性东西。但是,一旦包含一个或多个 Lawnchair 适配器,在最坏的情况下视图将不会显示,或者在最好的情况下它会更新位置/URI 而不会更改视图(直到发出另一个事件,如“更改”)。

$scope['login'] = function()
{
    AuthSvc.query(
        {'username':$scope['username'], 'password':$scope['password']},
        function( results )
        {
            LastUsedRsc.save({'key':'credentials', 'value':
                {'username':$scope['username'], 'password':$scope['password']}});
            $location.path( '/dataset' );
        },
        function( error )
        {
            alert( "Incorrect username and/or password." );
        });
    return( false );
};

我已经尝试过 $scope.$apply()、$scope.$digest()、它们各自的“安全”包装器等。这里有一个JSFiddle 供您查看。如果您删除 Manage Resources 下的 Lawnchair 适配器并再次运行 fiddle,您将看到视图将开始工作,但 Lawnchair 现在一文不值,因为没有任何东西真正持久化。在使用 Lawnchair 的一个适配器时,我需要做什么来更改视图?

【问题讨论】:

    标签: angularjs deferred lawnchair


    【解决方案1】:

    在解决了LoginResolverDatasetResolver 上的promise 之后,您确实需要运行$digest$apply

    例子:

    var LoginResolver = {
        'credentialsAsync':function( $rootScope, $q, $route, LastUsedRsc ) {
            var deferred = $q.defer();
            LastUsedRsc.get( 'credentials', function( object ) {
                deferred.resolve( object );
                $rootScope.$digest();
            },
            function( error ) {
                window.console.info( "Using default, default value.", error );            
                deferred.resolve({'value':{}});      
                $rootScope.$digest();
            });
        return( deferred.promise );
        },
    };
    

    注意:需要注入$rootScope并在resolve/reject后调用$digest

    【讨论】:

    • 我无法记住在解析/拒绝延迟对象后调用$digest 的单个示例。所以,我回去浏览了我浏览器上的大约 20 个标签,但没有一个有。他们要么对此一言不发,要么建议在 promise 的 then 回调中调用 $apply(这会导致讨论“应用已在进行中”错误)。谢谢!
    • @MarkMYoung,您可以使用$apply 代替$digest。您通常会看到 $apply 被使用,因为它“更安全”,尽管 CPU 成本更高。它更安全,因为它会检查所有范围内的所有手表是否有变化,这也是它更昂贵的原因。 $digest 只检查当前范围及其子范围的手表。在 $rootScope 上,你使用哪个并不重要,因为所有的手表都会被检查。
    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 2014-07-22
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    相关资源
    最近更新 更多