代码之家  ›  专栏  ›  技术社区  ›  Eric Mitjans

使用AngularJS用$http调用的结果填充指令

  •  2
  • Eric Mitjans  · 技术社区  · 12 年前

    我有一个指令,它从网格中计算被单击元素的位置并将其定位到位。

    到目前为止,该指令出现在它应该出现的位置,但我试图触发一个$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 .

    我该朝哪个方向走?

    2 回复  |  直到 12 年前
        1
  •  2
  •   j.wittwer    12 年前

    您正在尝试使用 $http 而不将其作为依赖项注入。应包括使用 inline injection annotation ,像这样:

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

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

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

    但是(至少在您的plunker中)您没有将其包含在指令元素标记中。按如下方式添加:

    <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 在指令中。这是一个工作中的笨蛋: http://plnkr.co/ttV0ZowaL8Tyz1hAkZak

        2
  •  1
  •   Brocco    12 年前

    我认为你的指令做得太多了。我将在控制器上处理所有事件,并在服务中处理ajax调用。

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

    artists
        releases
            release info
    

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

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