#angularjs #angular-ui-router
#angularjs #angular-ui-router
Вопрос:
У меня есть маршрут, в angular-ui-router
котором есть дочерние маршруты; Я хочу, чтобы ссылки на эти дочерние маршруты были видны только на родительском маршруте. Они присутствуют в меню, которое видно для всего приложения, но каждая ссылка зависит от параметра url в родительском для работы, поэтому крайне важно, чтобы они не были интерактивными, когда этот параметр не существует.
Итак, настройка такая;
.state('route1', {
url: '/route1/:id',
views: { 'main@': { template: '<route1-component></route1-component>' } }
})
.state('route1.child1', {
url: '/child1',
views: { 'main@': { template: '<route1-child1-component></route1-child1-component>' } }
})
Я получил возможность скрывать их для работы, используя ui-sref
в сочетании с ui-sref-active-eq
, используя этот макет…
<div ui-sref="route1" ui-sref-active-eq="visible" hidden>
<a ui-sref="route1.child1" ui-sref-opts="{ location: true, inherit: true, relative: true }">CHILD 1</a>
</div>
Сначала это работает нормально; Ссылка видна только тогда, когда мы находимся на route1
маршруте. URL, который он показывает #/route1/1/child1
, включает :id
параметр текущего URL.
Но когда я нажимаю на ссылку, URL-адрес мигает как #/route1/1/child1
на короткое мгновение, но затем route1
снова отображается.
Если я удалю ui-sref-active-eq
часть, она правильно перенаправит на дочерний маршрут. Но тогда у меня проблема с тем, что он не скрыт в противном случае.
Есть ли что-нибудь, что можно сделать?
Пожалуйста, обратите внимание, я использую исключительно компоненты angular 1.5 . Я вообще не использую обычные контроллеры или директивы. Это все 100% компоненты.
Это не совсем идеально, но это пример того, как все устроено, и я попытался прояснить, как они должны функционировать. Кажется, я не могу получить $state
внутри директивы для наблюдения за изменениями. https://plnkr.co/edit/rxjVbckhwxdYPRAX4uiU?p=preview
Комментарии:
1. в худшем случае создайте свою собственную директиву, которая использует
$state.includes()
или другие утилиты, встроенные в$state
2. Я не уверен, как вы будете прослушивать изменение состояния там. Похоже, это не работает, когда я подключаюсь
$stateChangeStart
к$rootScope
чему-либо, кромеrun
функции конфигурации модуля.3. также может быть введен
$state
в директиву. создайте демонстрацию, которая повторяет проблему4. Да, это не работает.
.directive('uiSrefVisible', function () { return { restrict: 'A', controller: function($rootScope, $state, $stateParams) { $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ console.log('test'); }) }, link: function (scope, element, attributes) { } } })
5. Это просто не работает. Он никогда не запускается. Единственное место, где он запускается, находится внутри начальной
run
функции.
Ответ №1:
следующее добавляет контроллер к вашему компоненту sidenav и использует $stateChangeSuccess
событие и $state.includes()
для обновления логического значения, переданного ng-show
.component('sidenav', {
controller: function ($rootScope,$state) {
var vm = this;
vm.isRoute1=$state.includes('route1');
$rootScope.$on('$stateChangeSuccess', function(evt, to, from){
vm.isRoute1=$state.includes('route1');
});
},
template: `
<div ng-show="$ctrl.isRoute1">
<a ui-sref="route1.child1" ui-sref-opts="{ location: true, inherit: true, relative: true }">
ROUTE 1 CHILD 1 LINK
</a>
</div>`
})
Я думаю, что это то поведение, которое вы хотите… однако не уверен на 100%
Комментарии:
1. Вау! Это не совсем поведение, но оно демонстрирует принцип. Я думаю, что я могу достаточно легко абстрагировать это от чего-то более масштабируемого. Спасибо за работу со мной. Честно говоря, это первый раз, когда я написал какой-либо angular на чистом javascript, так что это было довольно запутанно, начиная с typescript.
2. настоятельно рекомендуем избегать именования пользовательских директив с префиксами, которые очень близки к существующим модулям, иначе позже вы не поймете, что они не являются частью этого модуля
3. Это было больше просто для примера. Хотя я, похоже, не могу повторить это в Typescript … это очень своеобразно. Кажется, я просто не могу заставить
$rootScope.$on
его сработать. Это действительно странно…4. я начал делать это как директиву, и если вам нужна масштабируемость, то директива может быть лучшим подходом… затем может передавать привязки через атрибуты
5. Однако это не имеет особого смысла. Он отлично работает на контроллере компонентов в вашем примере, но когда я помещаю его в машинопись,
$rootScope
он есть. Я могу распечатать его. Но$on
никогда не срабатывает. Это просто так caddywhompus.