Заполнение директивы результатами вызова $http с использованием AngularJS
У меня есть директива, которая вычисляет положение элемента, по которому щелкают, из сетки и позиционируется на месте.
Пока директива появляется там, где она должна быть, но я пытаюсь вызвать вызов $ 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 ответа
Вы пытаетесь использовать $http
в директиве, не вводя его в качестве зависимости. Это должно быть включено, используя встроенную аннотацию впрыска, как это:
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 в список зависимостей директив:
angular.module('myApp').directive('theDirective', function($http, $compile) {...
Когда вы закончите манипулировать DOM, скомпилируйте элемент:
var collapse = angular.element('<div>' ...
...
$compile(collapse)(scope);
Я исправил несколько других вещей, но они не имеют отношения к использованию $http
в директиве. Вот рабочий плункер: http://plnkr.co/ttV0ZowaL8Tyz1hAkZak
Я думаю, что вы пытаетесь сделать слишком много в своей директиве. Я бы обработал все ваши события на вашем контроллере и вызовы ajax в сервисе.
Что касается вашей разметки я бы вложил в следующем
artists
releases
release info
Вы можете переключать статус видимости каждого слоя в вашем контроллере и загружать необходимые данные при необходимости.
Затем я включил бы очень простую директиву, чтобы управлять позиционированием и только позиционированием деталей релиза.