【问题标题】:Populating directive with the results of an $http call using AngularJS使用 AngularJS 使用 $http 调用的结果填充指令
【发布时间】:2014-04-02 15:30:44
【问题描述】:

我有一个指令,它从网格中计算点击元素的位置并定位在适当的位置。

到目前为止,指令出现在它应该出现的位置,但我正在尝试触发 $http 调用来填充指令(每个单击的元素调用一次),到目前为止我没有运气。

您可以在此处查看指令代码:

angular.module('myApp')

  .directive('theDirective',  [function() {
  return {
    restrict: 'A',
    scope: { position: '@', last: '@', release: '='},
    link: function(scope, element, attrs) {

      element.bind('click', function() {

        // Makes http call to get versions

        function getVersions(id){
          $http.get('http://api.discogs.com/masters/' + release.id + '/versions').
            success(function (data5) {
              $scope.versions = data5.versions;
          });
        }      

        // Highlight clicked element
        angular.element(document.querySelector('.clicked')).removeClass('clicked');
        element.addClass('clicked');
        // Create the collapse element or select existing one
        var collapseQuery = document.querySelector('#collapse');
        var collapse = collapseQuery === null ?
          angular.element('<div id="collapse" class="col-md-12 col-xs-12"> \
                <div class="inner"> \
                  <ul> \
                    <li class="title">{{release.title}}</li> \
                    <li class="row top" ng-show="versions"> \
                      <div class="col-md-1">Year</div> \
                      <div class="col-md-3">Format</div> \
                      <div class="col-md-3">Label</div> \
                      <div class="col-md-2">Country</div> \
                      <div class="col-md-2">Cat. Nº</div> \
                    </li> \
                    <li class="row" ng-show="versions" ng-repeat="version in versions | filter: \'!file\' | orderBy: version.released"> \
                      <div class="col-md-1">{{(version.released | release:4) || \'-----\'}}</div> \
                      <div class="col-md-3">{{version.format}}</div> \
                      <div class="col-md-3">{{version.label}}</div> \
                      <div class="col-md-2">{{version.country}}</div> \
                      <div class="col-md-2">{{version.catno}}</div> \
                    </li> \
                    <li class="row top" ng-hide="!release.format"> \
                      <div class="col-md-1">Year</div> \
                      <div class="col-md-3">Format</div> \
                      <div class="col-md-3">Label</div> \
                    </li> \
                    <li class="row" ng-hide="!release.format"> \
                      <div class="col-md-1">{{release.year}}</div> \
                      <div class="col-md-3">{{release.format}}</div> \
                      <div class="col-md-8">{{release.label}}</div> \
                    </li> \
                  </ul> \
                </div> \
              </div>') :
          angular.element(collapseQuery);

        // Based on the position of the clicked element calculate the rounded number up to the nearest multiple of four
        var calculatedPosition = Math.ceil(scope.position / 4) * 4;

        // Get the element at the calculated position or the last one
        var calculatedQuery = document.querySelector('[position="' + calculatedPosition + '"]');
        if (calculatedQuery === null) calculatedQuery = document.querySelector('[last="true"]');;

        var calculatedElement = angular.element(calculatedQuery);

        // Insert the collapse element after the element at the calculated position
        calculatedElement.after(collapse);

        // Highlight the calculated element
        angular.element(document.querySelector('.calculated')).removeClass('calculated');
        calculatedElement.addClass('calculated');
      });

      scope.$on('$destroy', function() {
        element.unbind('click');
      });


    }
  };
}
]);

我还发了Plunker

关于我应该采取哪个方向的任何指示?

【问题讨论】:

    标签: javascript angularjs using-directives


    【解决方案1】:

    您试图在指令中使用$http 而不将其作为依赖项注入。应该使用inline injection annotation 将其包含在内,如下所示:

    angular.module('myApp').directive('theDirective', function($http) {...
    

    您的$http 调用使用了release 范围属性,

    $http.get('http://api.discogs.com/masters/' + scope.release.id + '/versions').
    

    但是(至少在您的 plunkr 中)您没有将其包含在指令元素标记中。像这样添加它:

    <div the-directive release="release" ng-repeat="release in releases...
    

    最后,您的指令在动态创建的元素中显示$http 调用的结果。要在这个元素中实现绑定,你需要compile它。因此,将 $compile 添加到指令依赖项列表中:

    angular.module('myApp').directive('theDirective', function($http, $compile) {...
    

    完成对 DOM 的操作后,编译元素:

    var collapse = angular.element('<div>' ...
    ...
    $compile(collapse)(scope);
    

    我修复了一些其他问题,但它们与在指令中使用 $http 并没有真正的关系。这是一个工作的 plunker:http://plnkr.co/ttV0ZowaL8Tyz1hAkZak

    【讨论】:

    • 您好!您的解决方案正在填充指令,但无论出于何种原因,一旦单击发布并显示结果,这些相同的结果将填充以下单击(它不会更新为检索到的新信息),并且它也会被重复(例如:首先调用结果是名称为示例的版本,版本 A、B 和 C,当我单击另一个版本时,结果显示版本名称示例(不更新 release.name)和版本 A、A、A、B、B、B、C, C,C。知道为什么会这样吗?
    • 现在就试试吧。我怀疑这与试图重用现有的折叠元素有关。我每次都更新了 plunker 以重新创建它,现在我看不到问题。
    • 现在效果很好。我还为 http 返回 404 的情况创建了一个条件,并且它完美集成。谢谢!
    【解决方案2】:

    我认为你试图在你的指令中做太多事情。我会处理你控制器上的所有事件,以及服务中的 ajax 调用。

    至于你的标记我会嵌套如下

    artists
        releases
            release info
    

    您可以在控制器中切换每个图层的可见性状态,并在需要时加载必要的数据。

    然后我将包含一个非常基本的指令来处理定位,并且只处理发布细节的定位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 2022-01-18
      • 2020-05-26
      • 1970-01-01
      • 2020-05-12
      相关资源
      最近更新 更多