使用“&”绑定从隔离范围指令返回承诺

Returning a promise from isolate scope directive with `&` binding

In this plunk 我有一个指令数组,return 一个承诺映射到控制器中的一个函数,但是 $scope.run.thenundefined。这段代码有什么问题?

HTML

  <div ng-repeat="item in items">
      <div dir1 x="item.x" on-complete="item.onComplete()"></div>
  </div>

Javascript

angular.module("app", [])

.controller('ctl', function($scope) {

  $scope.run.then(function(response){
      alert(response);
  });

  $scope.items = [{x: 1, onComplete: $scope.run},
                 {x: 2, onComplete: $scope.run},
                 {x: 3, onComplete: $scope.run}];

})

.directive('dir1', function ($timeout,$http) {
    return {
        restrict: 'EA',          
        scope: {
            x: '=',
            onComplete: '&'         
        },
        link: function (scope, element, attrs) { 
            scope.onComplete = $http.get('page.html');
        }
    };
})
.directive('dir1', function ($timeout,$http) {
    return {
        restrict: 'EA',          
        scope: {
            x: '<',
            onComplete: '&'         
        },
        link: function (scope, element, attrs) {
            scope.$watch("x", function(newValue) {
                if (newValue) {
                    var url = "page"+newValue+".html"; 
                    var httpPromise =  $http.get(url);
                    scope.onComplete({$promise: httpPromise});
                };
            });
        }       
    };
})

使用表达式 & 绑定时,已解析的表达式求值函数接受局部变量上下文对象。

当指令调用 scope.onComplete(locals) 函数时,on-complete 属性定义的 Angular 表达式将使用父作用域进行计算。在局部上下文对象中定义的任何变量都将覆盖父作用域变量。

指令创建的承诺公开为 $promise

推荐: 用美元符号前缀局部变量 $ 以区别于父作用域变量。

有关详细信息,请参阅 AngularJS Comprehensive Directive API Reference - scope

用法

  <div ng-repeat="item in items">
      <div dir1 x="item.x" on-complete="item.onComplete($promise)"></div>
  </div>
.controller('ctl', function($scope) {
    
      $scope.items = [
                 {x: 1, onComplete: run},
                 {x: 2, onComplete: run},
                 {x: 3, onComplete: run}
      ];

      function run(promise) {
          promise.then(function(response){
              console.log("OK", response.status);
              console.log("URL", response.config.url); 
          }).catch(functon(response) {
              console.log("ERROR",response.status);
              console.log("URL", response.config.url);
          });
      };
})