Tengo una directiva desplegable construida sobre Angular Bootstrap typeahead.

Quiero que el consumidor de la directiva pueda proporcionar un atributo (límite a lista) que determina si la entrada del usuario se limita o no a los miembros de la lista. En la directiva uib-typeahead, esto se logra estableciendo el atributo typeahead-editable "true" o "false"

Debido a que mi directiva encapsula la uib que genera el menú desplegable, necesito cambiar la plantilla de mi directiva para cambiar su comportamiento en consecuencia, pero no puedo entender cómo se puede hacer eso. Intenté modificar la plantilla de cadena en la cláusula de devolución de mi directiva, pero eso no funciona, supongo que porque el valor de la plantilla se lee antes de que se procese la función de devolución.

Aquí está la directiva:

angular.module("app").directive("dropDown",  function () {
  var mt=mydropdowntemplate;

  return {
    link: function (scope, element, attrs) {
        var limitToList = attrs["limit-to-list"]=="false"; 
        var editable = !limitToList;
        if (editable) {
            mt=mt.replace("typeahead-editable='false'","typeahead-editiable='true'");
        }
        console.log("template: "  + mt )
        var list = scope[attrs["list"]];
        var length=list.length
        var valueName = attrs["value"];
        var idName = attrs["key"];       
    },
    template: mt  //This has the value of mt prior to the replace function above    
  }
})

Al mirar la página, puedo ver que la plantilla real utilizada fue la anterior al cambio aplicado en el bloque de resultados.

Enlace Plunker

2
GGizmos 17 oct. 2018 a las 02:21

2 respuestas

La mejor respuesta

La función link es un lugar inapropiado para modificar la plantilla ya que se ejecuta después de compilar la plantilla. En su lugar, use la forma de función de la propiedad de plantilla para modificar la plantilla:

angular.module("app").directive("dropDown",  function () {
  var mt=mydropdowntemplate;

  return {
    link: function (scope, element, attrs) {
        var list = scope.$eval(attrs.list);
        var length=list.length
        var valueName = attr.value;
        var idName = attrs.key;       
    },
    template: function (tElem, tAttrs) {
         var limitToList = tAttrs.limitToList=="false"; 
         var editable = !limitToList;
         if (editable) {
             mt=mt.replace("typeahead-editable='false'","typeahead-editiable='true'");
         }
        console.log("template: "  + mt )
        return mt;
    } 
  }
})

Para obtener más información, consulte Referencia de API de directiva integral de AngularJS - plantilla .

2
georgeawg 17 oct. 2018 a las 16:33

Utilice la propiedad 'alcance' del objeto devuelto para pasar datos a través de atributos. Así, puede usar la propiedad 'bindToController ", si usa la sintaxis controllerAs. Bueno, recomiendo encarecidamente usar el enfoque de componente en reemplazo de la directiva.

2
natqe 16 oct. 2018 a las 23:34