angularjs - tpls - ¿Es posible cambiar el bootstrap angular uib-dropdown templateUrl dinámicamente?
uib-pagination angularjs (2)
EDITAR : Debe asignar el valor de template-url
usando un controlador var que cambia cuando el usuario seleccione cualquiera de las opciones, luego "vuelve a pintar" el componente, de esta manera el "nuevo" menú desplegable se "vuelve a pintar" con la nueva plantilla.
Sí, es posible según la documentación oficial , aunque nunca he hecho esto antes.
Puede especificar una configuración de uib-menú desplegable llamada template-url
.
Según los documentos,
el valor predeterminado es ninguno
y
usted puede especificar una plantilla para el menú desplegable
Deseo cambiar dinámicamente la plantilla uib-dropdown
cuando el usuario haga clic en uno de sus <li>
, tal como podría "navegar" dentro de ese menú desplegable.
Traté de hacerlo a través de templateUrl
, pero ni las ng-templates
ni los parciales independientes pueden cambiar la plantilla desplegable de forma dinámica, como lo demuestra este plunkr .
Mi objetivo es crear una navegación con facetas a través de este menú desplegable para crear consultas visualmente, como se ve en el rastreador Sprint de Fieldbook (se requiere una cuenta) , que es algo así como Pure Angular Advanced Searchbox , pero estoy teniendo problemas abrumadores con esta biblioteca.
¿Es esto posible usar solo AngularJS y angular-bootstrap?
Demo (prueba el último):
http://plnkr.co/edit/1yLmarsQFDzcLd0e8Afu?p=preview
¿Cómo hacer que funcione?
En función de su plunkr, debe cambiar
<div class="input-group" uib-dropdown auto-close="disabled">
<input type="text" class="form-control" placeholder="Click to start a visual query search..." autocomplete="off" uib-dropdown-toggle/>
<ul class="dropdown-menu" role="menu" ng-if="ctrl.dropdownReady" uib-dropdown-menu template-url="{{ctrl.dropdownTemplateFour}}">
</ul>
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
</button>
</span>
</div>
a
<div class="input-group" uib-dropdown auto-close="disabled" ng-if="ctrl.dropdownReady">
<input type="text" class="form-control" placeholder="Click to start a visual query search..." autocomplete="off" uib-dropdown-toggle/>
<ul class="dropdown-menu" role="menu" uib-dropdown-menu template-url="{{ctrl.dropdownTemplateFour}}">
</ul>
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
</button>
</span>
</div>
En el que ng-if="ctrl.dropdownReady"
se mueve al div.input-group
.
Y cambio
vm.dropdownReady = false;
console.log(''vm.dropdownReady ='', vm.dropdownReady, '' partial = '', partial);
switch (template) {
case ''word'':
partial ? vm.dropdownTemplateFour = ''word-dropdown-dom.template.html'' : vm.dropdownTemplateThree = ''word-dropdown-dom.html'';
break;
case ''main'':
partial ? vm.dropdownTemplateFour = ''main-dropdown-dom.template.html'' : vm.dropdownTemplateThree = ''main-dropdown-dom.html'';
break;
}
vm.dropdownReady = true;
a
vm.dropdownReady = false;
console.log(''vm.dropdownReady ='', vm.dropdownReady, '' partial = '', partial);
switch (template) {
case ''word'':
partial ? vm.dropdownTemplateFour = ''word-dropdown-dom.template.html'' : vm.dropdownTemplateThree = ''word-dropdown-dom.html'';
break;
case ''main'':
partial ? vm.dropdownTemplateFour = ''main-dropdown-dom.template.html'' : vm.dropdownTemplateThree = ''main-dropdown-dom.html'';
break;
}
$timeout(function(){
vm.dropdownReady = true;
});
Que tiene un $timeout
wrap the vm.dropdownReady = true;
. Y deberías inyectar $timeout
a mano;
Mantenga el menú abierto
De acuerdo con la documentación , podemos elegir el estado inicial del menú desplegable con is-open
attr. Y podemos escuchar el evento de alternar con at on-toggle
attr. Entonces, si queremos mantener el menú abierto después de que el usuario haga clic en la entrada, debemos establecer los atributos de uib-dropdown
así:
<div class="input-group" uib-dropdown auto-close="disabled" ng-if="ctrl.dropdownReady" is-open="ctrl.open" on-toggle="ctrl.toggled(open)">
Y en el controlador:
vm.toggled = function (open) {
// the parameter `open` is maintained by *angular-ui/bootstrap*
vm.open=open;//we don''t need to init the `open` attr, since it''s undefined at beginning
}
Una vez que el menú está abierto, no se cierra sin que el usuario vuelva a hacer clic en la entrada.
¿Por qué?
Revisemos este fragmento :
$templateRequest(self.dropdownMenuTemplateUrl)
.then(function(tplContent) {
templateScope = scope.$new();
$compile(tplContent.trim())(templateScope, function(dropdownElement) {
var newEl = dropdownElement;
self.dropdownMenu.replaceWith(newEl);//important
self.dropdownMenu = newEl;
$document.on(''keydown'', uibDropdownService.keybindFilter);
});
});
El fragmento de arriba muestra cómo angular-ui / bootstrap usa el template-url attr para recuperar la plantilla y ponerla en práctica. Reemplaza el elemento ul
original con un elemento creado recientemente. Es por eso que el uib-dropdown-menu
y template-url
encuentra después de hacer clic en el ul
. Como no existen, ya no puedes cambiar la url de la plantilla con encuadernación angular.
El motivo por el que se ejecuta vm.dropdownReady = true;
inmediatamente después de vm.dropdownReady = false;
no funciona es que angular no tiene posibilidad de detectar este cambio y ejecutar el "ng-si" para eliminar realmente el dom. Debe hacer que la conmutación de vm.dropdownReady
asíncrona para dar la oportunidad angular de lograr esto.