【问题标题】:Proper Way to Handle Asynchronous Updates in Angular Controller在 Angular 控制器中处理异步更新的正确方法
【发布时间】:2015-02-23 23:08:21
【问题描述】:

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

查看:

<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 内部与 Angular 外部”,但在我看来,我并没有在这里“脱离 Angular”。

  2. 我知道我可以调用 $scope.$apply(),但我遇到了“digest is already in progress”错误,而且我似乎不必这样做。

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

【问题讨论】:

  • 它真的成功了吗?你能验证 vm.greeting 确实被设置了吗?
  • @ribsies 是的。我编辑了这个问题的代码以摆脱所有无关的东西,但是超时正在解决并且我的 .then(success) 函数正在执行。当我在 Chrome 开发工具中调试范围并查看 angular.element($0).scope().root.greeting 的值时,我看到了正确的值。

标签: javascript angularjs asynchronous


【解决方案1】:

ng-show 不需要花括号

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

改变

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • $scope 的使用(或不使用)不是我的问题。使用“controller as...”语法意味着您不会将属性和函数分配给 $scope,而是分配给您的 Controller 对象。
    • 就像我说的我做的事情不同,但我会留下我的答案,因为我认为风格指南值得一读。
    • 将查看您引用的链接。我已经看了很多例子,但到目前为止喜欢这个指导:github.com/johnpapa/angularjs-styleguide
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    相关资源
    最近更新 更多