处理角控制器中异步更新的正确方法

Proper Way to Handle Asynchronous Updates in Angular Controller

本文关键字:方法 更新 异步 控制器 处理      更新时间:2024-03-31

这是我的设置——我有一个控制器,它使用一个服务来完成一些工作,然后异步返回数据。在这种情况下,数据是通过超时返回的,但在现实生活中,这会做一些更有趣的事情:

视图:

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

控制器:

(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);
})();

服务:

(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 );
})();

问题:

  1. 为什么当超时解决并且vm.greeting分配发生在我的控制器中时,我的视图没有更新?我见过有人描述"在Angular内部vs在Angular外部",但在我看来,我在这里并没有"在Anglar外部"。

  2. 我知道我可以调用$scope$apply(),但我遇到了"摘要已经在进行中"的错误,而且我似乎不应该这样做。

  3. 有没有更好的方法来组织我的组件?我还尝试过通过$rootScope广播事件,并在Controller中编写事件处理程序,但这种安排显示出相同的结果(即,当异步模型更改发生时,视图不会更新)。

ng show 不需要大括号

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

更改

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

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

您构建代码的方式与我通常所做的非常不同。查看此链接可以获得很棒的风格指南。http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/

至于您的问题,Angular使用$scope将控制器中的值绑定到视图。因此,您的控制器应该注入$scope,然后您可以用$scope.greeting代替vm.greeting.