不能简单地用ES6承诺更新在NG-重复数据? [英] can't simply use ES6 promise to update data in ng-repeat?

查看:233
本文介绍了不能简单地用ES6承诺更新在NG-重复数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立与角度和ES6承诺下钻列表。如果不使用答应我​​的code ++工程,如下面的代码片段演示了。您单击父时,它都会扩大了孩子们(只是foo和样本为简单起见巴)。

\r
\r

angular.module('示范',[])\r
  .controller('DemoController',['$范围,DataService的',函数($范围,dataSvc){\r
    $ scope.entities = dataSvc.loadInitialData();\r
  }])\r
  .directive('钻取',['$编译,DataService的',函数($编译,dataSvc){\r
    返回{\r
      限制:'A',\r
      范围: {\r
        实体:'='\r
      },\r
      控制器:函数($范围){\r
        $ scope.load =功能(){\r
          this.entity.subEntities = dataSvc.load();\r
        };\r
      },\r
      编译:函数(元素){\r
        VAR内容= element.contents()remove()方法。\r
        VAR编译= NULL;\r
\r
        返回功能(范围,元素){\r
          如果(!编译){\r
            编译= $编译(内容);\r
          }\r
\r
          编译(范围,功能(克隆){\r
            element.append(克隆);\r
          });\r
        };\r
      },\r
      模板:\r
        '<李NG重复=实体的实体>' +\r
          '&所述; A HREF =#纳克点击=负载()>&下;跨度纳克绑定=entity.name>&下; /跨度>&下; / A>' +\r
          '< UL向下钻取实体=entity.subEntities>< / UL>' +\r
        '< /李>'\r
    };\r
  }])\r
  。服务('的DataService',函数(){\r
    this.loadInitialData =功能(){\r
      返回[\r
        {\r
          名称:'富',\r
          subEntities:[]\r
        },\r
        {\r
          名称:'棒',\r
          subEntities:[]\r
        }\r
      ];\r
    };\r
    this.load =功能(){\r
      返回this.loadInitialData();\r
    };\r
  });

\r

&LT;脚本SRC =htt​​ps://cdnjs.cloudflare.com/ajax /libs/angular.js/1.3.0/angular.min.js\"></script>\r
&LT; D​​IV NG-应用=演示NG-控制器=DemoController&GT;\r
  &LT; UL向下钻取实体=实体&GT;&LT; / UL&GT;\r
&LT; / DIV&GT;

\r

\r
\r

然而,当我将其更改为使用的承诺,不顺心的事:现在你必须双击该元素将其展开和范围也搞砸了。

的区别是本质上的服务和指令控制器只是在负荷功能。到目前为止,我还没有真正看着角的 $ Q API,但为什么我不能只使用承诺?有一些神奇的还有在 $ Q

\r
\r

angular.module('示范',[])\r
  .controller('DemoController',['$范围,DataService的',函数($范围,dataSvc){\r
    $ scope.entities = dataSvc.loadInitialData();\r
  }])\r
  .directive('钻取',['$编译,DataService的',函数($编译,dataSvc){\r
    返回{\r
      限制:'A',\r
      范围: {\r
        实体:'='\r
      },\r
      控制器:函数($范围){\r
        $ scope.load =功能(){\r
          变种S =这一点;\r
          dataSvc.load()。然后(功能(RES){\r
            s.entity.subEntities =资源;\r
          });\r
        };\r
      },\r
      编译:函数(元素){\r
        VAR内容= element.contents()remove()方法。\r
        VAR编译= NULL;\r
\r
        返回功能(范围,元素){\r
          如果(!编译){\r
            编译= $编译(内容);\r
          }\r
\r
          编译(范围,功能(克隆){\r
            element.append(克隆);\r
          });\r
        };\r
      },\r
      模板:\r
        '&LT;李NG重复=实体的实体&GT;' +\r
          '&所述; A HREF =#纳克点击=负载()&GT;&下;跨度纳克绑定=entity.name&GT;&下; /跨度&GT;&下; / A&GT;' +\r
          '&LT; UL向下钻取实体=entity.subEntities&GT;&LT; / UL&GT;' +\r
        '&LT; /李&GT;'\r
    };\r
  }])\r
  。服务('的DataService',函数(){\r
    this.loadInitialData =功能(){\r
      返回[\r
          {\r
            名称:'富',\r
            subEntities:[]\r
          },\r
          {\r
            名称:'棒',\r
            subEntities:[]\r
          }\r
        ];\r
    };\r
    this.load =功能(){\r
      返回新希望(函数(解析,拒绝){\r
        解决([\r
          {\r
            名称:'富',\r
            subEntities:[]\r
          },\r
          {\r
            名称:'棒',\r
            subEntities:[]\r
          }\r
        ]);\r
      });\r
    };\r
  });

\r

&LT;脚本SRC =htt​​ps://cdnjs.cloudflare.com/ajax /libs/angular.js/1.3.0/angular.min.js\"></script>\r
&LT; D​​IV NG-应用=演示NG-控制器=DemoController&GT;\r
  &LT; UL向下钻取实体=实体&GT;&LT; / UL&GT;\r
&LT; / DIV&GT;

\r

\r
\r


解决方案

这将需要ES6承诺,无论是揭露一个钩子设置调度程序(如青鸟承诺),或揭露,那么后挂钩 - 两者都不是不公开。

您不得不要挟ES6承诺到 $ Q 一个接这样做的:

  $ q.when(dataSvc.load()),然后(...

另外,你可以写一个帮手绑定到一个范围:

  VAR withDigest =功能(FN){
    FN()。然后(函数(){
        $ rootScope.evalAsync(angular.noop); //时间表摘要,如果没有安排
    });
};

然后执行:

  withDigest(函数(){
    返回dataSvc.load()。然后(...
});

I'm trying to build a drill-down list with angular and es6 promise. Without using promise my code works as demoed in the snippet below. Every time you click the parent, it expands the children (just foo and bar in the sample for simplicity).

angular.module('demo', [])
  .controller('DemoController', ['$scope', 'dataService', function($scope, dataSvc) {
    $scope.entities = dataSvc.loadInitialData();
  }])
  .directive('drillDown', ['$compile', 'dataService', function($compile, dataSvc) {
    return {
      restrict: 'A',
      scope: {
        entities: '='
      },
      controller: function($scope) {
        $scope.load = function() {
          this.entity.subEntities = dataSvc.load();
        };
      },
      compile: function(element) {
        var contents = element.contents().remove();
        var compiled = null;

        return function(scope, element) {
          if (!compiled) {
            compiled = $compile(contents);
          }

          compiled(scope, function(clone) {
            element.append(clone);
          });
        };
      },
      template:
        '<li ng-repeat="entity in entities">' +
          '<a href="#" ng-click="load()"><span ng-bind="entity.name"></span></a>' +
          '<ul drill-down entities="entity.subEntities"></ul>' +
        '</li>'
    };
  }])
  .service('dataService', function() {
    this.loadInitialData = function() {
      return [
        {
          name: 'foo',
          subEntities: []
        },
        {
          name: 'bar',
          subEntities: []
        }
      ];
    };
    this.load = function() {
      return this.loadInitialData();
    };
  });

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
<div ng-app="demo" ng-controller="DemoController">
  <ul drill-down entities="entities"></ul>
</div>

However when I change it to using promise, something goes wrong: now you'd have to double click the element to expand it and the scopes are also messed up.

The difference is essentially just in the load function in the service and the directive controller. So far I haven't really looked into angular's $q api but why can't I just use promise? Is there some magic there in $q?

angular.module('demo', [])
  .controller('DemoController', ['$scope', 'dataService', function($scope, dataSvc) {
    $scope.entities = dataSvc.loadInitialData();
  }])
  .directive('drillDown', ['$compile', 'dataService', function($compile, dataSvc) {
    return {
      restrict: 'A',
      scope: {
        entities: '='
      },
      controller: function($scope) {
        $scope.load = function() {
          var s = this;
          dataSvc.load().then(function(res) {
            s.entity.subEntities = res;
          });
        };
      },
      compile: function(element) {
        var contents = element.contents().remove();
        var compiled = null;

        return function(scope, element) {
          if (!compiled) {
            compiled = $compile(contents);
          }

          compiled(scope, function(clone) {
            element.append(clone);
          });
        };
      },
      template:
        '<li ng-repeat="entity in entities">' +
          '<a href="#" ng-click="load()"><span ng-bind="entity.name"></span></a>' +
          '<ul drill-down entities="entity.subEntities"></ul>' +
        '</li>'
    };
  }])
  .service('dataService', function() {
    this.loadInitialData = function() {
      return [
          {
            name: 'foo',
            subEntities: []
          },
          {
            name: 'bar',
            subEntities: []
          }
        ];
    };
    this.load = function() {
      return new Promise(function(resolve, reject) {
        resolve([
          {
            name: 'foo',
            subEntities: []
          },
          {
            name: 'bar',
            subEntities: []
          }
        ]);
      });
    };
  });

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
<div ng-app="demo" ng-controller="DemoController">
  <ul drill-down entities="entities"></ul>
</div>

解决方案

This would require ES6 promises to either expose a hook for setting the scheduler (like bluebird promises) or to expose "post-then" hooks - neither of which it does publicly.

You'd have to coerce the ES6 promise to a $q one by doing:

$q.when(dataSvc.load()).then(...

Alternatively, you can write a helper for binding it to a scope:

var withDigest = function(fn){
    fn().then(function(){
        $rootScope.evalAsync(angular.noop); // schedule digest if not scheduled
    });
};

And then do:

withDigest(function(){
    return dataSvc.load().then(...
});

这篇关于不能简单地用ES6承诺更新在NG-重复数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆