javascript - not - angularjs parent child controller communication
Cómo configurar la vista secundaria predeterminada con el enrutador de UI angular (3)
¡En la versión 1.0.0alpha0 finalmente lo hacen posible! No es hijo para estados abstractos, nuevo $ transitionsProvider , en el que puede definir onBefore hook. Puede cambiar el comportamiento dependiendo de las opciones de estado.
Por ejemplo, puede cambiar el comportamiento param "abstracto":
$transitionsProvider.onBefore({
to: state => !!state.abstract
}, ($transition$, $state) => {
if (angular.isString($transition.to().abstract)) {
return $state.target($transition.to().abstract);
}
});
y usalo asi
abstract: ''abstract2.foo'', //use not boolean but exact child state
se tomó de: ui-router: hijo predeterminado para el estado abstracto
Digamos que tengo los siguientes 3 estados de enrutador de interfaz de usuario angular:
$stateProvider
.state(''adminCompanies'', {
abstract: true,
url: "/admin/companies",
template: ''<div ui-view class="viewContainer" autoscroll="false" />''
})
.state(''adminCompanies.list'', {
url: "",
templateUrl: ''app/admin/companies/companies.list.html'',
controller: ''AdminCompaniesController''
})
.state(''adminCompanies.detail'', {
url: "/:companyId",
templateUrl: ''app/admin/companies/companies.detail.html'',
resolve: {
company: function(Model, $stateParams) {
return Model.get("/admin/companies", $stateParams.companyId);
}
},
controller: ''AdminCompanyDetailController''
})
Si las adminCompanies
se adminCompanies
directamente, ¿cómo puedo decirle al Angular UI Router que vaya al estado adminCompanies.list
lugar?
Idealmente, lo que me gustaría es algo como:
$stateProvider.when(''adminCompanies'', ''adminCompanies.list'');
En mi código, quiero que $ state.go (''adminCompanies'') sea equivalente a $ state.go (''adminCompanies.list'')
Como su aplicación está configurada actualmente, no debería necesitar ninguna lógica explícita para esto. Cuando un subestado tiene una propiedad de url
vacía, se activa al mismo tiempo que se activa su estado principal. Cualquier plantilla para el subestado se inserta en la directiva ui-view
proporcionada por la plantilla del estado principal. La aplicación de ejemplo Angular UI se dirige a este tipo de arquitectura: cuando se navega hacia el estado de los contacts
, su template proporciona el diseño de navegación así como una ui-view
de interfaz de usuario distinta para sus subestados; Debido a que el estado de contacts.list
tiene una propiedad url
de ""
, se carga automáticamente cuando se encuentra en su estado principal, se navega a los contacts
Esto está documentado en los comments la aplicación:
Usar una URL vacía significa que este estado secundario se activará cuando se navegue por la URL de su padre. Las urls de estados secundarios se agregan automáticamente a las urls de sus padres. Así que la url de este estado es ''/ contacts'' (porque ''/ contacts'' + '''').
Ahora, suponiendo que por alguna razón u otra, usted nunca quiso que su estado principal de adminCompanies
. En este caso, puedes hacer que ese estado sea un estado abstract así:
$stateProvider
.state(''adminCompanies'', {
abstract: true,
url: "/admin/companies",
template: ''<div ui-view class="viewContainer" autoscroll="false" />''
})
.state(''adminCompanies.list'', {
url: "/list",
templateUrl: ''app/admin/companies/companies.list.html'',
controller: ''AdminCompaniesController''
})
.state(''adminCompanies.detail'', {
url: "/:companyId",
templateUrl: ''app/admin/companies/companies.detail.html'',
resolve: {
company: function(Model, $stateParams) {
return Model.get("/admin/companies", $stateParams.companyId);
}
},
controller: ''AdminCompanyDetailController''
})
Tenga en cuenta la adición del abstract: true
adición en la tercera línea y la url explícita del estado de /list
para adminCompanies.list
Esto le dice a Angular-UI que debe tratar este estado como si no existiera para propósitos de navegación de URL. Sin embargo, seguirá activo cuando navegue a subestados, por lo que seguirá utilizando la URL que proporcione para prefijar la URL de subestados. Pero si intenta navegar hacia él desde otro estado, actuará como si el estado no existiera. Por este motivo, también deberá agregar el manejo de las URL no $urlRouteProvider
usando $urlRouteProvider
.
Un uso básico de $urlRouteProvider
podría tener este aspecto:
$urlRouterProvider.otherwise("/")
Eso simplemente redirige todas las llamadas a estados no existentes al estado con la URL de "/". Esto supone que tienes uno. Sin embargo, debido a que alguien podría estar intentando navegar a la vista de lista pero está navegando a /admin/companies
directamente, probablemente debería tener un controlador como este:
$urlRouterProvider.when("/admin/companies", "/admin/companies/list");
El que use depende de la arquitectura de su aplicación, pero parece que para sus necesidades actuales no debería tener que hacer nada. Si sus especificaciones cambian, el estado abstracto puede ser útil.
También puede usar ui-router-default : un módulo donde los estados secundarios predeterminados se definen en el estado principal configurando el abstract: ".defaultChild"
.
Esto tiene la ventaja de poder usar ui-sref="parent"
y $state.go("parent");
(lo que fue importante para mí al crear dinámicamente una barra de navegación).
NB: tanto esta como la solución de David solo funcionan si el estado primario es abstracto, es decir, el padre no puede estar activo sin que esté activo un niño, lo que debería ser el caso cuando queremos tener una vista infantil "predeterminada".
(Vea también la discusión relevante del equipo ui-router here .)