Ссылки 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, время: 08:42. |