¿Cómo modelar estructuras If-Else en vistas vinculadas a datos?


95

Constantemente me encuentro usando este idioma en plantillas HTML basadas en KO:

<!-- ko if: isEdit -->
<td><input type="text" name="email" data-bind="value: email" /></td>
<!-- /ko -->
<!-- ko ifnot: isEdit -->
<td data-bind="text: email"></td>
<!-- /ko -->

¿Existe una forma mejor / más limpia de hacer condicionales en KO, o hay un enfoque mejor que simplemente usar las construcciones tradicionales if-else?

Además, me gustaría señalar que algunas versiones de Internet Explorer (IE 8/9) no analizan correctamente el ejemplo anterior. Consulte esta pregunta SO para obtener más información. El resumen rápido es que no use comentarios (enlaces virtuales) dentro de las etiquetas de la tabla para admitir IE. Utilice en su tbodylugar:

<tbody data-bind="if: display"><tr><td>hello</td></tr></tbody>

Cualquiera que vea
Brian M. Hunt

Respuestas:


64

Hay un par de formas diferentes de manejar este tipo de código.

  • con una combinación si / si no como lo es ahora. Esto funciona bien y no es muy detallado.

  • El enlace de interruptor / caso de Michael Best ( https://github.com/mbest/knockout-switch-case ) es bastante flexible y puede permitirle manejar fácilmente esto y otros más complicados (más estados que verdadero / falso).

  • Otra opción es utilizar plantillas dinámicas. Uniría un área a una o más plantillas con el nombre de la plantilla que se usa según un observable. Aquí hay una publicación que escribí sobre este tema hace un tiempo: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html . En su escenario, podría verse así:

<td data-bind="template: $root.getCellTemplate"></td>

<script id="cellEditTmpl" type="text/html">
    <input type="text" name="email" data-bind="value: email" />
</script>

<script id="cellTmpl" type="text/html">
    <span data-bind="text: email"></span>
</script>

La getCellTemplatefunción podría vivir en cualquier lugar, pero se le daría el elemento ($ data) como primer argumento y devolvería el nombre de la plantilla a usar.


extraño, mi HTML no aparecerá. También me di cuenta de que Michael dio prácticamente la misma respuesta.
RP Niemeyer

Gracias por una lista completa de opciones. Supongo que mi estilo de código original funciona para casos simples. Verificaré las otras opciones cuando surja la necesidad.
Jensen Ching

¿Hay alguna manera de personalizar la plantilla aún más, como "template: data, proppertyName: 'email'" y en la plantilla data-bind = "text: $ data [propertyName]"?
Onur Topal

@OnurTOPAL: sí, siempre que tenga una variable propertyName, puede determinar dinámicamente el nombre de la plantilla.
RP Niemeyer

44

Un enfoque es utilizar plantillas con nombre (que pueden admitir el paso de argumentos):

<!-- ko template: isEdit() ? 'emailEdit' : 'emailDisplay' --><!-- /ko -->
<script id="emailEdit" type="text/html">
    <td><input type="text" name="email" data-bind="value: email" /></td>
</script>
<script id="emailDisplay" type="text/html">
    <td data-bind="text: email"></td>
</script>

Otra opción es usar mi complemento switch / case , que funcionaría así:

<!-- ko switch -->
    <!-- ko case: isEdit -->
        <td><input type="text" name="email" data-bind="value: email" /></td>
    <!-- /ko -->
    <!-- ko case: $else -->
        <td data-bind="text: email"></td>
    <!-- /ko -->
<!-- /ko -->

Gracias. Tendré en cuenta el complemento switch / case para cuando surja la necesidad.
Jensen Ching

2
¡Buen plugin que llegaste! Usaré este seguro.
Kukks

Las plantillas con nombre funcionan muy bien y admiten escenarios de tipo if elseif elseif else anidando el operador ternario.

4

Para evitar que se vuelva a calcular el enlace de nocaut cuando se usa una combinación de if: / ifnot: puede usarlos junto con la construcción 'with:'

    <!-- ko with: $data.DoSomePerformanceCriticalWork($data.SomeParameter()) -->
        <!-- ko if: $data.Condition() -->
           ... some markup ...
        <!-- /ko -->
        <!-- ko ifnot: $data.Condition() -->
           ... some markup ...
        <!-- /ko -->
    <!-- /ko -->

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.