2015-10-29 2 views
0

Я создаю веб-приложение, и у меня есть экран, состоящий из пяти разделов, каждый раздел представляет уровень, области - это более высокий уровень моего дерева, когда я нажимаю любой карты области, система должна вернуть навыки этой области и так далее. wireframeНесколько состояний и URL-адресов для одного и того же шаблона

Мне нужно изменить URL и состояние в зависимости, что пользователь получает доступ, к примеру, если пользователю доступ некоторый навык, URL-адрес должен быть

example.com/#/curriculum/skill/<skillId> 

и если доступ к этой ссылке он должен автоматически загружает возможности этого умения и его родителя, который является областью в этом случае.

У меня есть один контроллер для области, умения, способности, знания и критерии, в каждом контроллере у меня есть действие, чтобы загрузить следующий уровень дерева, который выглядит, что

$scope.loadSkills = function (id) { 
    Area.loadSkills(...) 
    $state.go('curriculo.skill', {id: this.current.id}, {nofity: false, reload: false}); 
} 

И это мое заявляет

$stateProvider 
     .state('curriculum', { 
     url: '/curriculum', 
     templateUrl: '/templates/curriculo.html', 
     }) 
     .state('curriculum.are', { 
     url: '/area/:id', 
     template: '', 
     }) 
     .state('curriculum.skill', { 
     url: '/skill/:id', 
     template: '', 
     }) 
     .state('curriculum.capability', { 
     url: '/capability/:id', 
     }) 
     .state('curriculum.knowledge', { 
     url: '/knowledge/:id', 
     }) 
     .state('curriculum.criteria', { 
     url: '/criteria/:id', 
     }); 

Я новичок в Угловом, и я не уверен, что делать, если я создал несколько вложенных представления в этом случае, и если да, то как я могу загрузить вещи, которые мне нужны по URL-адрес?

ответ

2

Я бы предложил использовать возможности нескольких именованных видов, предлагаемых ui-router. Вы можете узнать больше об этом here. В основном документация говорит следующее:

Вы можете назвать свои взгляды, так что вы можете иметь более одного UI-вид за шаблона.

Если вы проверяете пример в документации, вы будете notive, что есть сходство между вашим сценарием и, например, потому что вы хотите, чтобы динамически заполнить различные views (здесь именованные виды).

Пример

Я пытался воссоздать свой сценарий в этом JSFiddle.

Сначала я создал abstract состояния, которое обеспечивает различные views как районы, навыки и т.д. Это шаблон для абстрактного состояния:

<div class="curriculum" ui-view="areas"></div> 
<div class="curriculum" ui-view="skills"></div> 

Затем я создал вложенное состояние curriculo.main, которое декларирует различные точки зрения (области, навыки и т. д.). Каждый вид имеет свои template и controller. Обратите внимание, что вложенное состояние имеет resolve, который изначально загружает области из службы под названием curriculo. Если вы используете resolves, помните, что ключевое слово solve ДОЛЖНО относиться к состоянию, а не к представлениям (при использовании нескольких видов).

В основном служба несет ответственность за бизнес-логику, означает получение областей, навыков и т. Д. В JSFiddle у меня есть жестко закодированные результаты HTTP. Замените это на HTTP-вызовы и используйте обещания. Поскольку каждый именованный вид имеет свой собственный контроллер, нам нужен механизм для уведомления об изменениях, например, чтобы уведомить SkillsController, что навыки были загружены.Таким образом, я создал простую систему событий (subcribe-извещать):

.factory('notifier', function($rootScope) { 
    return { 
     subscribe: function(scope, callback, eventName) { 
      var handler = $rootScope.$on(eventName, callback); 
      scope.$on('$destroy', handler); 
     }, 
     notify: function(eventName, data) { 
      $rootScope.$emit(eventName, data); 
     } 
    }; 
}); 

SkillsController затем может подписаться на конкретное событие так:

notifier.subscribe($scope, function(event, data) { 
    $scope.skills = data; 
}, 'onSkillsLoaded'); 

The curriculo обслуживания вызовов (на конце getSkills()) notify и предоставляет событие. В этом случае одно и то же событие, на которое вы подписаны в SkillsController.

notifier.notify('onSkillsLoaded', result); 

В целом, это волшебство за моим маленьким примером. Стоит упомянуть, что вам нужно применять лучшие методы для кода, так как это просто для воссоздания вашего сценария. Для лучшей практики я предлагаю Angular Style Guide от John Papa.

Update 1

Я обновил свой пример, чтобы показать вам глубокие ссылки. Я смоделирую глубокую ссылку через

$state.go('.', {area: 2, skill: 5}); 

Таким образом, я могу активировать определенное состояние. Теперь каждый вид имеет свою функцию activate. Внутри этой функции я выполняю всю работу, которая является незаменимой для инициализации, например. выбор области, если задан параметр запроса. Как вы знаете, вы можете получить доступ к параметрам с помощью службы $state. Мне пришлось использовать $timeout для задержки инициализации контроллера зон, потому что подписка еще не была выполнена. Попробуйте найти лучшее решение этой проблемы. Возможно, вы можете использовать обещания или регистрировать каждый контроллер в службе, которая разрешает, если весь контроллер был инициализирован.

Если что-то было выбрано, я также использую go с дополнительной возможностью установить notify на false.

$state.go('.', {area: area.id, skill: skillId ? skillId : undefined}, {notify: false}); 

Если notify установлен в false это предотвратит контроллеры от переинициализации. Таким образом, вы можете обновлять только URL-адрес, и никаких изменений состояния не произойдет.

+0

Есть ли способ изменить URL-адрес в зависимости от того, к чему пользователь обращается? Потому что есть момент, когда мне нужно отправить уведомление пользователю и построить всю структуру по указанному URL-адресу. И спасибо за быстрый ответ :) –

+0

Обновлен мой ответ. Это то, что вы хотите? Но теперь попробуйте реализовать его сами :) вернитесь, если у вас возникнут проблемы. Если бы этот ответ был в порядке, я был бы признателен за принятие. – LordTribual

Смежные вопросы