Ссылки ui-sref со {{scope}} не всегда отрабатывают
Добрый день.
Динамически строю меню разделов категорий. Пишу ссылки так:
<a ui-sref="{{CurrentPageForCategory}}.category({category:'+data[i].subrecords[j].id+'})">'+data[i].subrecords[j].name+'</a>
CurrentPageForCategory получаю из контроллеров. В каждом контроллере вывожу в консоль для проверки. В итоге, в консоль у меня все выводится как нужно, а вот при нажатии на ссылку иногда появляется ошибка и переход не выполняется. Говоря "Иногда" подразумеваю так: Обновил страницу - работает. Обновил страницу, снова работает, обновил - не работает, обновил - работает. То есть, если сразу с загрузкой страницы заработало, то и будет работать, если сразу с загрузкой страницы не заработало, то не будет работать. Ошибка: angular.js:13920 Error: Could not resolve '.category' from state '' Покопавшись понял, что ангуляр не всегда мне строит ссылку, то есть глядя в код страницы вижу, что когда работает, то у меня к ссылке добавляется href="ссылка", когда не работает, то href-а нет в ссылке. Возможно, это из-за того, что у меня иногда CurrentPageForCategory не передается в ссылку, хотя при просмотре кода страницы, он всегда есть в ui-sref. Пробовал добавлять сразу href в ссылку, она точно так же у меня всегда есть и всегда заполнена, но иногда ссылка все равно не отрабатывает показывая все ту же ошибку angular.js:13920 Error: Could not resolve '.category' from state '' По сути у меня должно быть не '.category' а 'catalog.category'/ В чем может быть дело? |
Меню у меня строится в директиве, есть это построение добавить в
setTimeout(function(){
построение меню
});
Тогда вроде нормально отрабатывает. Но ведь это наверное не выход? |
и то с setTimeout не всегда срабатывает.
|
Вообще - делай пример, потому что ничего не понятно по сути.
Но есть предположение что инфу о категориях ты получаешь асинхронно и передаешь ее в директиву. Так вот - на момент открытия страницы с директивой которая юзает какие либо данные - эти данные уже должны быть доступны! |
все верно, сначала в контроллере я делаю http запрос, затем в директиве результат использую.
Пример попробую сделать. Суть в том, что я в директиве совсем не красивым способом с помощью чистого js делаю меню с помощью двух циклов. Меню представляет собой аккордион. Если бы можно было как-то сделать с помощью ng-repeat, то я бы сделал, ведь туда данные попадут после загрузки и отрисовка тогда и начнется. мне нужен аккордион по такой разметке:
<div id="accordion">
<h3>Пункт 1</h3>
<div>Контент 1</div>
<h3>Пункт 2</h3>
<div>Контент 2</div>
<h3>Пункт 3</h3>
<div>Контент 3</div>
</div>
Как мне такой цикл сделать с помощью стандартной директивы не понятно. |
.controller("IndexCtrl", function ($scope, $http) {
$scope.setCurrentPageForCategory = function(CurrentPageForCategory){ //функция для присвоения значения в других контроллерах и передачи в родительский controller
$scope.CurrentPageForCategory = CurrentPageForCategory;
};
$http.get("http://localhost/modules/index/index.php").then(function(response) {
$scope.categories = response.data.categories;
}, function(error) {});
});
// Директива в которой строится аккордион. Выглядит все это очень плохо, не красиво и не правильно.
.directive("categoriesList", function($compile) {
return function(scope, element, attributes) {
var attrValue= attributes['categoriesList'];
var data=scope[attrValue];
if (angular.isArray(data)) {
for (var i = 0; i < data.length; i++) {
var e = angular.element("<h3>");
element.append(e);
e.text(data[i].name);
var e = angular.element("<div>");
element.append(e);
for (var j = 0; j < data[i].subrecords.length; j++) {
var content = $compile(e.html() + '<a ui-sref="{{CurrentPageForCategory}}.category({category:'+data[i].subrecords[j].id+'})">'+data[i].subrecords[j].name+'</a>' + '<br>')(scope);
e.html(content);
}
}
}
$("#accordion h3").addClass('accordion-not-active');
$("#accordion h3").click(function() {
$(this).toggleClass('accordion-active accordion-not-active');
});
$('#accordion').accordion();
}
});
Шаблон HTML <div id="accordion" ng-if="categories" categories-list="categories"></div> |
Вообще пример-это рабочий пример кода а не пару портянок кода. Для примеров есть такие сервисы как jsfiddle codepen и пр.
Вобщем, у тебя два варианта: 1 если ты используешь uirouter то выполни подгрузку категорий в resolve https://github.com/angular-ui/ui-router/wiki 2 ты можешь использовать в директиве $scope.$watch для того чтобы перегенерить меню как только обновится моделька которую вотчишь. |
resolve сделал, на первый взгляд теперь после каждой перезагрузки страницы стабильно работает ссылка. НО по какой-то причине перестал обновляться href. Решил проблему с помощью ng-href.
Все таки интересует вопрос, как можно сделать ng-repeat, чтобы получить вот такой результат:
<div id="accordion">
<h3>Пункт 1</h3>
<div>Контент 1</div>
<h3>Пункт 2</h3>
<div>Контент 2</div>
<h3>Пункт 3</h3>
<div>Контент 3</div>
</div>
|
А в чем сложность то?
<div id="accordion" ng-repeat="cat in categories">
<h3 ng-bind="cat.name"></h3>
<div ng-bind="cat.content"></div>
</div>
|
Таким кодом создается
<div id="accordion">
<h3>Пункт 1</h3>
<div>Контент 1</div>
</div>
<div id="accordion">
<h3>Пункт 2</h3>
<div>Контент 2</div>
</div>
<div id="accordion">
<h3>Пункт 3</h3>
<div>Контент 3</div>
</div>
|
Возвращаясь к сообщению #7.
Ссылка то обновляется, но переход осуществляется на старую ссылку. Пример: <a class="tst ng-scope" ui-sref="offers.category({category:12})" ng-href="/offers/12" href="/offers/12">Женская одежда</a> Щелкая на эту ссылку перехожу по адресу: /company/12 Уже думаю, может два меню сделать, столько времени убил на это меню. |
Цитата:
<div id="accordion">
<div ng-repeat="cat in categories">
<h3>Пункт 1</h3>
<div>Контент 1</div>
</div
</div>
И вообще, такие структуры делаются с помощью <ul><li></li></ul> Цитата:
Делать 2 меню? Зачем? Что бы не работало что то еще? Не вижу логики. Поднапрягись - заюзай резолв, выпили дикий скрипт формирования меню. Максимум что ты должен сделать - это сформировать объект с нужной тебе структурой вложенности пунктов меню. И в нем должны быть конкретные данные, никаких html тегов. И потом этот объект нужно вывести с помощью ngrepeat. Все. |
Ничего подобного, watch не делал, сделано с resolve:
.state('companys', {
resolve:{
simpleObj: function(){
return {value: 'companys'};
}
},
url: "/companys",
views: {
'@': {
templateUrl: function($stateParams) {
return UseURL + mUrl + "companys/categoryAll.html"
},
controller: 'ctrlCompanyAll'
}
}
})
|
Ну ок, тогда не вижу для тебя никаких проблем, кроме возможно формата данных присылаемых по запросу категорий. Надеюсь это Json.
В общем не знаю что тебе еще сказать. Если все равно не получается сделай тестовый пример со стабом на список категорий, посмотрим |
Начал изучать angular2. От 1.5 отказался. Спасибо за помощь.
|
| Часовой пояс GMT +3, время: 20:12. |