简体   繁体   English

在Angular Controller中处理异步更新的正确方法

[英]Proper Way to Handle Asynchronous Updates in Angular Controller

Here's my setup -- I have a controller that is using a service that does some work and then returns data asynchronously. 这是我的设置-我有一个使用服务的控制器,该服务执行一些工作,然后异步返回数据。 In this case, the data is returned by a timeout, but in real life this would do something more interesting: 在这种情况下,数据是通过超时返回的,但是在现实生活中,这样做会更有趣:

View: 视图:

<div ng-controller="RootController as root">

  <h1>Angular Project</h1>
  <div ng-show="{{root.greeting}}">
    <p>{{root.greeting}}</p>
  </div>

</div>

Controller: 控制器:

(function(){

  'use strict';

  function RootController(greetingService) {

    var vm = this;
    vm.greeting = '';

    // startup logic
    activate();

    function activate() {
        greetingService.greeting().then(
          function( response ) {
              vm.greeting = response;
          },
          function( error ) {
              vm.greeting = error;
          }
        );
    }
  }
  RootController.$inject = ['greeting'];
  angular.module('app.core').controller('RootController', RootController);

})();

Service: 服务:

(function() {
  'use strict';

  // Greeting Service
  function greeting( $timeout ) {

    // public API
    var service = {
        greeting:   greeting
    };
    return service;

    // internal functions
    function greeting() {
        return $timeout( function() {
            return 'Hello world!'; 
        }, 1000 );
    }

  }

  temp.$inject = ['$timeout'];
  angular.module('app.core').factory( 'greeting', greeting );

})();

Questions: 问题:

  1. Why is it that my view is not updating when the timeout resolves and the vm.greeting assignment occurs in my controller? 为什么当超时解决并且控制器中发生vm.greeting分配时,我的视图没有更新? I've seen people describe "inside Angular vs outside Angular", but it would seem to me that I haven't gone "outside Angular" here. 我见过人们形容“ Angular内部与Angular内部”,但是在我看来,我并没有在“ Angular外部”进行过描述。

  2. I'm aware that I can call $scope.$apply(), but I've encountered the " digest is already in progress " error, and again it doesn't seem like I should have to do this. 我知道我可以调用$ scope。$ apply(),但是我遇到了“ 摘要已在进行中 ”错误,看来我也不必这样做。

  3. Is there a better way I should be organizing my components? 有没有更好的方式来组织组件? I have also experimented with broadcasting an event over $rootScope and writing an event handler in the Controller, but this arrangement exhibits the same outcome (namely the view is not updated when the asynchronous model change occurs). 我还尝试了通过$ rootScope广播事件并在Controller中编写事件处理程序,但是这种安排表现出相同的结果(即,发生异步模型更改时,视图不会更新)。

You don't need the curly braces for ng-show ng-show不需要花括号

https://docs.angularjs.org/api/ng/directive/ngShow https://docs.angularjs.org/api/ng/directive/ngShow

change 更改

<div ng-show="{{root.greeting}}">

to

<div ng-show="root.greeting">

The way you have structured your code is a very different from what I normally do. 您构造代码的方式与我通常的做法大不相同。 Check out this link for a great style guide. 查看此链接,获取出色的风格指南。 http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/ http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/

As for your issue, Angular uses $scope to bind a value in the controller to the view. 对于您的问题,Angular使用$ scope将控制器中的值绑定到视图。 So your controller should have $scope injected and you can then do$scope.greeting in place of vm.greeting. 因此,您的控制器应注入$ scope,然后可以执行$ scope.greeting代替vm.greeting。

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

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