pasar - sintaxis angular




Selección dinámica de componentes en Angular2 (2)

  1. Como dice el error, un componente debe tener un selector único. Si desea vincular el comportamiento del componente al selector de atributos como con [type='bool'] , debería usar directivas. Use selector='bool-field' para su BoolComponent .

  2. Como dice el error, su componente <field> genérico no tiene un atributo de type al que vincularse. Puede solucionarlo agregando una variable miembro de entrada: @Input() type: string;

  3. Desea delegar la plantilla del componente a un solo componente que recibe un atributo de type . Simplemente cree ese componente genérico y otros componentes que lo usan solo tendrán que proporcionarlo, no sus hijos.

Ejemplo: http://plnkr.co/edit/HUH8fm3VmscsK3KEWjf6?p=preview

@Component({
  selector: 'generic-field',
  templateUrl: 'app/generic.template.html'
})
export class GenericFieldComponent {
  @Input() 
  fieldInfo: FieldInfo;
}

usando la plantilla:

<div>
  <span>{{fieldInfo.caption}}</span>

  <span [ngSwitch]="fieldInfo.type">
    <input  *ngSwitchWhen="'bool'" type="checkbox" [value]="fieldInfo.value === 1">  
    <input  *ngSwitchWhen="'text'" type="text" [value]="fieldInfo.value">  
    <select  *ngSwitchWhen="'options'" type="text" [value]="fieldInfo.value">
      <option *ngFor="let option of fieldInfo.options" >
        {{ option }}
      </option>
    </select>  
  </span>
</div>

Esta pregunta ya tiene una respuesta aquí:

Dado un modelo para una sección de página que contiene múltiples campos y se llenaría con datos como este:

{
    "fields": [
        {
            "id": 1,
            "type": "text",
            "caption": "Name",
            "value": "Bob"
        },
        {
            "id": 2,
            "type": "bool",
            "caption": "Over 24?",
            "value": 0
        },
        {
            "id": 3,
            "type": "options",
            "options" : [ "M", "F"],
            "caption": "Gender",
            "value": "M"
        }
    ]
}

Me gustaría tener una sección genérica Componente que no conozca los diferentes tipos de campos que podría envolver, para evitar mucha lógica condicional en la plantilla de sección y para hacer nuevas vistas / componentes de tipo de campo agregados al colocar un auto -contenido contenido en lugar de tener que modificar un componente separado.

Mi ideal sería que el selector de un Componente sea lo suficientemente específico como para poder lograr esto seleccionando un elemento en la plantilla del Componente principal en función de los valores de atributo vinculados al modelo. Por ejemplo: (perdone cualquier problema de sintaxis ya que lo codifiqué en la ventana SO, la parte principal a la que debe prestar atención es el selector en BooleanComponent.ts

SectionComponent.ts

@Component({
    selector: 'my-app'
})
@View({
    template: `
        <section>
            <div *ng-for="#field of fields">
                <field type="{{field.type}}"></field>
            </div>  
        </section>
    `,
    directives: [NgFor]
})
class SectionComponent {
    fields: Array<field>;
    constructor() {
        this.fields = // retrieve section fields via service
    }
}

FieldComponent.ts:

// Generic field component used when more specific ones don't match
@Component({
    selector: 'field'
})
@View({
    template: `<div>{{caption}}: {{value}}</div>`
})
class FieldComponent {
    constructor() {}
}

BooleanComponent.ts:

// specific field component to use for boolean fields
@Component({
    selector: 'field[type=bool]'
})
@View({
    template: `<input type="checkbox" [id]="id" [checked]="value==1"></input>`
})
class BooleanComponent {
    constructor() {}
}

... y con el tiempo agregaría nuevos componentes para proporcionar plantillas y comportamientos especiales para otros tipos de campos específicos, o incluso campos con ciertos subtítulos, etc.

Esto no funciona porque los selectores de componentes deben ser un nombre de elemento simple (en alpha.26 y alpha.27 al menos). Mi investigación de las conversaciones de github me llevó a creer que esta restricción se estaba relajando, pero no puedo determinar si lo que quiero hacer será realmente compatible.

Alternativamente, he visto un DynamicComponentLoader mencionado, aunque ahora no puedo encontrar el ejemplo que pensé que estaba en la guía angular.io. Aun así, no sé cómo podría usarse para cargar dinámicamente un componente para el que no conoce el nombre o los criterios coincidentes.

¿Hay alguna manera de lograr mi objetivo de desacoplar componentes especializados de sus padres utilizando una técnica similar a la que probé o alguna otra técnica que no conozco en Angular 2?

ACTUALIZACIÓN 2015-07-06

http://plnkr.co/edit/fal9OA7ghQS1sRESutGd?p=preview

Pensé que era mejor mostrar los errores con los que me encuentro más explícitamente. He incluido un plunk con algún código de muestra, aunque solo el primero de estos 3 errores será visible, ya que cada uno bloquea al otro, por lo que solo puede mostrar uno a la vez. Por el momento, he codificado para sortear los n. ° 2 y n. ° 3.

  1. Si mi selector en BooleanComponent es selector: 'field[type=bool]' o selector: '[type=bool]' , obtengo una pila de errores de Angular como

    El componente 'BooleanComponent' solo puede tener un selector de elementos, pero tenía '[type = bool]'

  2. <field [type]="field.type"></field> no vincula mi valor de field.type al atributo type, pero me da este error (que afortunadamente aparece ahora en alpha 28. En alpha 26 estaba previamente encendido, falló en silencio). Puedo deshacerme de este error al agregar una propiedad de tipo a mi FieldComponent y al derivado BooleanComponent y conectarlo con la colección de propiedades @Component, pero no lo necesito para nada en los componentes.

    No se puede vincular a 'tipo' ya que no es una propiedad conocida del elemento 'campo' y no hay directivas coincidentes con una propiedad correspondiente

  3. Me veo obligado a enumerar FieldComponent y BooleanComponent en la lista de directivas de mi anotación SectionComponent View, o no se encontrarán ni se aplicarán. Leí las discusiones de diseño del equipo de Angular donde tomaron esta decisión consciente a favor de lo explícito con el fin de reducir la aparición de colisiones con directivas en bibliotecas externas, pero rompe la idea de los componentes que estoy tratando de lograr.

En este punto, me cuesta ver por qué Angular2 incluso se molesta en tener selectores. El componente padre ya tiene que saber qué componentes secundarios tendrá, a dónde irán y qué datos necesitan. Los selectores son totalmente superfluos en este momento, bien podría ser una convención de coincidencia de nombre de clase. No veo la abstracción entre los componentes que necesitaría para desacoplarlos.

Debido a estas limitaciones en la capacidad del marco Angular2, estoy haciendo mi propio esquema de registro de componentes y colocándolos a través de DynamicComponentLoader, pero aún sentiría mucha curiosidad por ver las respuestas de las personas que han encontrado una mejor manera de lograr esto. .


Me tomó un tiempo, pero veo lo que estás tratando de hacer. Básicamente, cree una biblioteca de formularios imperativa para ng2, como angular-formly. Lo que intenta hacer no está cubierto en los documentos, pero podría solicitarse. Las opciones actuales se pueden encontrar en las anotaciones de las líneas 419 - 426 .

Esta solución sobre-seleccionará y generará falsos positivos, pero pruébelo.

Cambie <field type="{{field.type}}"></field> a <field [type]="field.type"></field>

Luego seleccione para atributo:

@Component({
  selector: '[type=bool]'
})






angular