Ember.js: [Glimmer 2] "Retroceder el renderizado" ahora es una afirmación

Creado en 29 jul. 2016  ·  63Comentarios  ·  Fuente: emberjs/ember.js

El re-renderizado con retroceso se refiere a un escenario en el que, en medio del proceso de renderizado, ha modificado algo que ya se ha renderizado.

Por ejemplo:

{{foo}} {{foo-bar parent=this}}
// app/components/foo-bar.js

export default Ember.Component.extend({
  init() {
    this._super(...arguments);
    this.get('parent').set('foo', 'bar');
  }  
});

Como puede ver, para cuando se crea una instancia y se renderiza el componente foo-bar , ya hemos usado el valor foo del contexto principal para completar el {{foo}} curly. Sin embargo, en su constructor, intentaba modificar el mismo valor, por lo tanto. "retroceder".

Este es un ejemplo bastante extremo, pero ilustra el problema. Además de init , didInitAttrs , didReceiveAttrs , willInsertElement y willRender también ocurre sincrónicamente durante el proceso de renderizado. Además, el retroceso es a menudo un problema que surge del comportamiento de las propiedades enlazadas bidireccionales.

Este comportamiento siempre ha sido poco confiable, pero fue parcialmente compatible con una desaprobación (desde Ember 1.13):

You modified ApplicationController.foo twice in a single render. This was unreliable in Ember 1.x and will be removed in Ember 3.0

Desde la versión 1.13, Ember apoyó esto haciendo inmediatamente una segunda re-renderización cuando se detectó un retroceso (y luego repitiendo hasta que el sistema se estabilice). Esta estrategia en sí misma podría ser una fuente de problemas de desempeño. En casos extremos, esto podría causar un bucle infinito.

En Glimmer 2, mientras que la reproducción adicional es relativamente barata, la contabilidad adicional para detectar un retroceso set no lo es. Una de las ventajas del sistema Glimmer 2 es que no necesita configurar observadores ansiosos para rastrear los cambios. Además, ciertas optimizaciones en Glimmer 2 permiten que el sistema se salte los subárboles que atraviesan cuando no sabe que nada dentro de ellos ha cambiado.

Juntos, estos factores significan que no podemos detectar fácilmente estos retrocesos set s (o si algo "ya estaba renderizado" o no) sin hacer una gran cantidad de contabilidad adicional y derrotar intencionalmente estas optimizaciones.

Ya escribimos el código para respaldar esto, pero debido a la naturaleza ya poco confiable de la función y los costos de contabilidad (muy significativos), dudamos en habilitarlos automáticamente para todos sin saber si aún es necesario.

Como compromiso, actualmente solo realizamos la detección en el modo de desarrollo y convertimos el mensaje de obsolescencia en una afirmación del modo de desarrollo (error grave). En el modo de producción, el código de detección se elimina y el retroceso no funcionará.

Hemos mantenido la posibilidad de admitir esta función (sin la aserción) en la base de código detrás de una segunda marca de función. El código se prueba continuamente en CI, sin embargo, está deshabilitado de forma predeterminada hasta que tengamos suficiente información de uso para determinar los próximos pasos.

Si cree que tiene patrones de uso que se ven afectados por esto, proporcione tantos detalles sobre su escenario como sea posible a continuación. Es muy posible que haya alternativas y / o soluciones específicas que podamos utilizar que no requieran un cambio total en el motor. Por lo tanto, sería útil proporcionar información básica y contexto sobre su uso en lugar de mostrarnos pequeños fragmentos de código de su base de código.

Ember 2.10 Inactive

Comentario más útil

Esto no se mencionó en la publicación del blog 2.10 y me tomó por sorpresa, ya que la advertencia de desaprobación decía anteriormente que sería compatible hasta 3.0, como se mencionó anteriormente.

Todos 63 comentarios

Para su información, teníamos algunas de estas advertencias en nuestra aplicación. Específicamente, actualizamos algunas propiedades de un servicio en el init de un componente, lo que haría que algo más en la página se renderizara de manera diferente.

Es muy sencillo solucionar esta advertencia programando el cambio de propiedad en el siguiente ciclo de ejecución. Me tomó ~ una hora rastrear y corregir todas las advertencias en nuestra aplicación (bastante grande). Aunque este es técnicamente un cambio importante, estoy de acuerdo con su evaluación incluso si me causó un trabajo adicional.

@fivetanley mejorar el mensaje de error aquí suena bien. Sé que @krisselden y @stefanpenner tienen un flujo de trabajo para rastrear estos problemas, tal vez puedan ayudarlo a darle algunas instrucciones al respecto.

@joukevandermaas run.next () no es una gran solución para este error, aunque entiendo que si estás abrumado con estos errores, deberías ir allí. Es mejor tratar de comprender por qué el flujo de retorno de datos invalida las cosas que ya se procesaron.

Probablemente, si establece accesorios en un servicio que podría inyectarse en cualquier componente, aumentan las posibilidades de que ese conjunto invalide algo que ya se ha procesado. En general, el patrón debe ser que set () solo se use en el estado interno durante los ganchos de renderizado, no vinculado a la entrada o servicios y / o set () se use en un evento, el estado de entrada debe establecerse por el tiempo que se procesa el material.

@joukevandermaas run.next () no es una gran solución para este error,

si lo hace, provocará problemas de rendimiento, ya que, en este caso, glimmer2 informa "está sucediendo un trabajo duplicado, realmente no quiere esto si quiere una aplicación de rendimiento". Donde anteriormente, la brasa absorbería esto, pero resultaría en una penalización de rendimiento considerable.

Tenemos más trabajo para compartir conocimientos aquí ... En última instancia, creemos que este es un camino saludable para las aplicaciones. Pero debemos asegurarnos de que todos tengan las herramientas y el conocimiento disponibles para beneficiarse :)

Como persona que sigue a Ember relativamente de cerca (twitter, aquí en github, listas de correo, etc.), este problema se me coló, así que sospecho que esto podría tomar a otros por sorpresa si aterriza como parte de Ember 2.10, particularmente porque la advertencia de desaprobación asociada con él indica específicamente que el comportamiento será compatible hasta la versión 3.0. No creo que lo haya visto socializado en ningún lado que este comportamiento no funcionará en Glimmer 2 (aunque es posible que simplemente lo haya pasado por alto).

Sospecho que esto podría tomar a otros por sorpresa si aterriza como parte de Ember 2.10, particularmente porque la advertencia de depreciación asociada con él establece específicamente que el comportamiento será compatible hasta 3.0. No creo que lo haya visto socializado en ningún lado que este comportamiento no funcionará en Glimmer 2 (aunque es posible que simplemente lo haya pasado por alto).

sí, necesitamos mejorar algunos mensajes / detalles aquí.

Veo que esto llegó a la versión 2.10. ¿Se mencionará esto en la publicación de blog de la versión 2.10?

Esto no se mencionó en la publicación del blog 2.10 y me tomó por sorpresa, ya que la advertencia de desaprobación decía anteriormente que sería compatible hasta 3.0, como se mencionó anteriormente.

Tengo un patrón de uso que se ve afectado por esto. Estoy seguro de que el problema debe ser mi patrón de uso, y no este cambio en particular, ¡pero me encantaría recibir alguna información sobre lo que sería un buen patrón de uso alternativo!

Básicamente, tengo una página que muestra un conjunto de datos filtrables y, para lograrlo, estoy usando un valor calculado de Ember para filtrar los datos en función del valor de varios parámetros de consulta en la página. Sin embargo, para evitar que se agreguen entradas no válidas (por ejemplo, no letras o números) a los parámetros de consulta desde la entrada del usuario, tengo el siguiente patrón:

 filteredModel: Ember.computed('model', /*list of individual query params*/, function(){
    let model = this.get('model').filterBy('pdf.pdf_path.url'); //removes all records that don't have a pdf uploaded
    this.get('queryParams').forEach((filter)=> { // for each possible filter
      if ((this.get(filter).length > 0)) { //if the filter has content...
        //guardian pattern to prevent invalid inputs
        let valid = new RegExp('^[A-Za-z0-9 _]*[A-Za-z0-9][A-Za-z0-9 _]*$');
        while (this.get(filter).length > 0 && !valid.test(this.get(filter))){
          this.set(filter, this.get(filter).slice(0,-1));
        }
        //block of code where the model gets filtered
        //...
        //...
    });
    return model;
  }),

Entonces, básicamente, cuando calculé cómo debería verse el modelo filtrado, si alguno de los valores de filtro tiene caracteres no válidos, elimino el último carácter hasta que se vuelva válido. ¿Alguien tiene una sugerencia de una forma más limpia de verificar la validez de estas entradas?

Esto también nos tomó por sorpresa, particularmente porque no vimos ningún mensaje de advertencia cuando la aplicación se estaba ejecutando con 2.9. Cuando actualizamos a 2.10, la aplicación no se carga y hace referencia a este error. Alguien más ha visto este comportamiento?

@revanar Podría estar totalmente didReceiveAttrs . Desde mi experiencia con el error de "retroceso de reproducción", creo que mover la operación set fuera del CP debería hacer que el error desaparezca.

También estamos pasando por un momento difícil con esto. He solucionado muchos de los problemas, pero una instancia que estamos viendo de este error de desaprobación es desconcertante.

Assertion Failed: You modified transitioningIn twice on <app<strong i="6">@component</strong>:link-to::ember1159> in a single render.

Parece que se está produciendo un error porque una propiedad interna de la brasa se está actualizando más de una vez. Desafortunadamente, se reproduce durante nuestras pruebas de selenio, por lo que es difícil de depurar (el controlador de selenio evita que las herramientas de desarrollo funcionen mientras se ejecuta la prueba). Rastreé al menos una instancia del problema hasta una llamada controller.transitionToRoute realizada al final de nuestro proceso de inicio de sesión, pero parece suceder en varios escenarios diferentes.

No estoy seguro de cómo proceder con la solución de problemas.

@chancancode mencionó una https://github.com/emberjs/ember.js/blob/master/FEATURES.md. ¿Alguien sabe qué es la bandera?

Para nuestra migración de ember 2.10 también, este es el principal problema. También hemos solucionado muchos de estos problemas. Parece que no existe una estrategia única / clara para corregir estos errores. Hemos probado los siguientes enfoques, según el caso de uso.

  1. Envolver el código en Ember.run.next
  2. Mover cualquier código setter de computed properties a los ganchos del ciclo de vida, oa event handlers , siempre que sea posible.
  3. Probar una combinación diferente de ganchos de ciclo de vida para componentes

También hemos tenido muchas dificultades con esto. En los últimos años, hemos acumulado una buena cantidad de menús desplegables que seleccionan automáticamente el primer elemento de un cierto tipo de la memoria caché del almacén de datos de ember. Esto provoca una nueva representación, ya que algunas partes de la página están controladas por la selección desplegable. No estoy muy seguro de qué hacer, ya que no quiero repetir el mismo código para completar y seleccionar el primer elemento de la lista en cada página en la que se utilizan los menús desplegables.

@scottmessinger Gracias por los comentarios. El uso de un componente terminó funcionando bastante bien. Me las arreglé para deshacerme del error de retroceso, y creo que mi código es un poco más limpio para él.

Kris Selden tiene un consejo útil para depurar estos:

screen shot 2016-12-12 at 13 10 44

He descrito los pasos con más detalles aquí: https://github.com/GavinJoyce/backtracking/pull/1#issuecomment -266427152

Estoy trabajando para mejorar el mensaje de afirmación de retroceso . He cortado una compilación 2.10.2-with-improved-backtracking-assertion que incluye estos mejores mensajes:

Antes:

Modificó message.message_goal.description dos veces en <(subclass of Ember.Model):ember3486> en un solo render. Esto no era confiable y lento en Ember 1.xy ya no es compatible. Consulte https://github.com/emberjs/ember.js/issues/13948 para obtener más detalles.

Después:

Modificó message.message_goal.description dos veces en <(subclass of Ember.Model):ember3486> en un solo render. Se renderizó en component:message-edit-expanding-container-component y se modificó en component:rules/predicate-date-value-component . Esto no era confiable y lento en Ember 1.xy ya no es compatible. Consulte el n. ° 13948 para obtener más detalles.

Tengo algunas cosas más que hacer antes de que esté listo, pero sería realmente útil si algunas personas probaran esto en su aplicación. / cc @fivetanley , @bryanhickerson , @revanar , @phammers , @scottmessinger , @ tharrington1 , @ manimis902 , @jakesjews , @ elwayman02. Por favor, avíseme si ve algún mensaje de afirmación no ideal en su aplicación.

Para probarlo, actualice su bower.json para incluir la dependencia ember de la siguiente manera:

{
  "name": "backtracking",
  "dependencies": {
    "ember": "intercom/ember#2.10.2-with-improved-backtracking-assertion",
    "ember-cli-shims": "0.1.3"
  },
  "resolutions": {
    "ember": "2.10.2-with-improved-backtracking-assertion"
  }
}

Puede ver una aplicación de ejemplo que ejecuta esta compilación aquí: https://github.com/GavinJoyce/backtracking/pull/10

Acabo de cortar una compilación canary 1.11.0

¿Es esto un error tipográfico?

@rwjblue gracias, esto fue un error tipográfico. Actualizado

@GavinJoyce, ¡ gracias por

@Dhaulagiri, si está interesado, me complacerá organizar una pantalla

FWIW He encontrado otro problema relacionado con esto: https://github.com/alexspeller/ember-cli-active-link-wrapper/issues/25

También probé la rama de @GavinJoyce cuando intentaba encontrar un error en un esfuerzo continuo para llevar un control de pestañas a ember-paper (PR arriba mencionado). Desafortunadamente, parece que en mi caso también obtengo referencias a componentes que no parecen estar involucrados.

@bjornharrtell , ¿tienes una rama de papel de brasa que pueda probar?

^ Nos tomamos un poco de tiempo para sumergirnos en los problemas del papel de ascua (https://github.com/miguelcobain/ember-paper/pull/590). Parece que:

  • los nuevos mensajes de error fueron más útiles que el actual
  • no eran perfectos porque no manejaban bien el contenido producido. (el componente que contenía {{yield}} se informó como la fuente que fue útil, pero no tan útil como podría ser)

Puede o no ser un error con el complemento, pero encontré este error en https://github.com/DockYard/ember-one-way-controls/issues/136

Encontré un problema.
Estoy usando un mixin que tiene puntos de entrada para actualizar la misma propiedad para el controlador al que se mezcló. Estas son propiedades definitivamente diferentes porque simplemente pertenecen a diferentes controladores y la aserción falla y bloquea js.
Probé mixin desenvolviéndolo en algunos controladores e hice una transición entre las rutas para reproducirlo; no se reprodujo.

Por ahora, estoy tratando de deshacerme de los mixins, así que simplemente lo mataré y crearé una solución.

Creo que tengo un caso de uso válido en el que estamos viendo este problema de reproducción. En nuestra aplicación, tenemos un botón que contiene algún estado (ok, validando, advertencia, error). Es un componente que muestra el estado actual, valida cuando suceden ciertas cosas y, según el resultado de la validación o activación, muestra diferentes cosas (flechas, texto de botón diferente, clase de botón diferente).

Verificamos la validación en init() y, según la respuesta de validación, establecemos el estado del botón apropiado. La clase de botón es una propiedad calculada que establece las clases apropiadas según el estado del botón. Dado que ocurre en init, parece que este error se activa porque comenzamos con el estado de ok en la instanciación, luego pasamos a la validación ya que estamos validando la versión y el estado final en función de la respuesta. Sin embargo, el caso de uso en sí parece razonable y, por lo tanto, los cambios de estado que están ocurriendo también parecen razonables.

@ tundal45 ¿ podrías crear una aplicación de prueba o de muestra que demuestre lo que crees que es un error incorrecto?

@ Blackening999 @ tundal45 ¿puedes reducir tu caso de uso a un giro?

@chancancode @ Blackening999 Intentaré publicar uno aquí pronto. Gracias por una respuesta rápida.

@chancancode https://ember-twiddle.com/936d549b5625b0cf4f3c945d0ed04d3b?openFiles=components.button-with-state.js sería el twiddle, pero no veo el error que estoy viendo en la aplicación, por lo que podría ser otra cosa que lo está causando.

Veo esto en varias propiedades calculadas, una de las cuales es un Ember.computed.or simple. Dado que ninguna de las sugerencias de @ manimis902 es aplicable en este caso, ¿cuál sería una solución alternativa adecuada?

Como @ tharrington1 menciona, ¿dónde está la bandera para la función mencionada por @chancancode ?

@cbou que yo sepa, esa bandera no existe

No estaba completamente seguro de cómo manejar estos avisos de desaprobación, ni estoy seguro de si mi solución era / es válida, pero estaba haciendo una solicitud AJAX en el gancho del componente init() que desencadenó un cambio de valor en un propiedad del servicio (para rastrear / mostrar si accede al servidor remoto).

Moví mi código de solicitud AJAX del gancho del componente init() gancho del componente didRender() y parece haber resuelto mi aviso de depreciación.

@ lvl99 hice lo mismo.

Estamos esforzándonos por actualizar nuestro proyecto empresarial a Ember 2.12 desde 2.3. En nuestro proyecto, tenemos un complemento de validación y un complemento de componentes de formulario separado. El complemento de validación funciona en Ember.components para generar errores de validación y el complemento de componentes de formulario muestra los errores generados por el complemento de validación a través de un asistente. Los complementos son demasiado complicados para compartir el código fuente; de ahí que creamos el siguiente giro para ilustrar el caso al que nos enfrentamos.

El ejemplo dado contiene dos componentes ( person-detail y address-detail ) que son responsables de generar sus propios errores de validación. Los errores de validación generados por address-detail se conectan en cascada al componente contenedor ( person-detail ) mediante una acción lanzada dentro de la propiedad calculada errors . Los errores generados por cada componente se muestran dentro de un componente error-displayer con la ayuda del ayudante error-formatter . El código proporcionado funciona como se esperaba, como puede ver.

Sin embargo; tenemos una advertencia de desaprobación de la siguiente manera: DEPRECATION: The error property ofis an Ember.Binding connected to validatable.errors.name , but Ember.Binding is deprecated. Consider using an alias computed property instead. [deprecation id: ember-metal.binding] See http://emberjs.com/deprecations/v2.x#toc_ember-binding for more details. Para evitar eso; por favor vaya al ayudante error-formatter y comente la línea número 9 y descomente la línea número 8 para que estemos haciendo lo que se sugiere en la explicación de la advertencia.

Ahora llegamos al infame Assertion Failed: You modified "error" twice on <Ember.Object:ember338> in a single render. It was rendered in "component:error-displayer" and modified in "component:error-displayer". This was unreliable and slow in Ember 1.x and is no longer supported. See https://github.com/emberjs/ember.js/issues/13948 for more details. Entendemos por qué estamos recibiendo este error; porque la acción que se dispara dentro de address-detail s errors propiedad calculada da como resultado un nuevo cálculo de errors propiedad calculada de person-detail y el contenido que ya está renderizado está causando este error . Esto es lo que nos gustaría aprender:

  1. Ember.Binding vs Ember.computed.alias está funcionando de manera bastante diferente con seguridad en términos de la fase de recálculo (re-renderizado). ¿Cuál es la diferencia exacta? Sugerir el uso de este último como reemplazo del primero parece estar rompiendo el código; al menos para nuestro caso.
  2. ¿Es un problema desencadenar una acción desde una propiedad calculada? En caso afirmativo; ¿Cuáles son las posibles sugerencias para evitarlo?
  3. Estamos considerando la activación de la acción de ajuste dentro de una declaración Ember.run.scheduleOnce('afterRender', ...) . ¿Es este el camino correcto a seguir?
  4. Finalmente; por favor regrese al código de ruptura actual y escriba algo en cualquier campo; y, sorprendentemente, los componentes se repiten varias veces; sospechamos que esto podría estar relacionado con un error.

FWIW, he visto que mis componentes se vuelven a renderizar con más frecuencia de lo que esperaría en algunos casos. Rastrear la causa de una repetición requiere bastante tiempo porque a menudo se sincroniza con un runloop. Me encantaría saber si hay atajos o trucos de depuración en esta área.

¿Hay alguna forma de detectar o suprimir esta afirmación en las compilaciones de depuración? Hemos rastreado y solucionado esto a través de refactores como se describe anteriormente en la mayoría de los lugares, pero hay 1 o 2 que son bastante tercos. En un caso particular, estamos destruyendo un objeto y luego haciendo la transición. El objeto destruido (en nuestra API) envía una notificación de empujador para descargar / destruir varios objetos más.

En las compilaciones de producción, la re-renderización no es un problema, ya que solo estamos destruyendo el objeto y luego haciendo la transición de todos modos (por lo que se está derribando toda la ruta). Sin embargo, la afirmación sobre las compilaciones de desarrollo es bastante frustrante, ya que requiere una actualización para restaurar el sitio. Entiendo por qué estamos recibiendo el error, pero en este caso es un refactor bastante complicado para evitarlo, y en cualquier caso no importa ya que se está destruyendo toda la ruta. ¿Hay alguna forma de detectar / suprimir / cambiar esto a una advertencia? Probé un try / catch, así como el controlador de errores de la ruta, pero ninguno lo captó.

@ feanor07 enviando una acción desde get que invalida la propiedad que ya se ha renderizado es el flujo de retorno de datos, antes de que los enlaces con un ciclo detecten y elijan silenciosamente la dirección de avance como la ganadora, pero esto tiene un gran costo si esto fluye a través varias cosas y fluye de regreso a la fuente.

Básicamente, tiene una dependencia cíclica y necesita que los datos fluyan hacia abajo, no genere el error antes de ejecutar la validación. Puede validar en un componente principal que produce el modelo y los errores para representar el formulario dentro de su bloque.

@ feanor07 Ember.run.scheduleOnce... no funcionó, pero agregar solo un Ember.run.schedule("afterRender", () => { ... }); a la propiedad set indicada primero por el seguimiento de la pila eliminó muchos mensajes de error que caían en cascada después del inicial.

@neilthawani que puede ocultar el error, pero no necesariamente soluciona el problema. El error está destinado a indicar que está configurando un valor dos veces cuando probablemente solo debería configurarlo una vez. Al poner uno de los set en schedule , solo está retrasando el segundo conjunto para que suceda en un bucle de ejecución diferente. No ha solucionado el problema central de renderizar dos veces cuando solo necesita renderizar una vez, simplemente engañó a Ember para que no supiera que había un problema porque ahora las renderizaciones ocurren en ciclos de ejecución separados.

@ elwayman02 Uh oh. Gracias. Básicamente perdí el punto por completo.

Editar: Después de luchar con él, inserté algunos afterRenders que me sentía cómodo. Tenemos un controlador click en uno de nuestros componentes de visualización de datos que alterna una información sobre herramientas. Establecer la bandera isDisplaying dentro de un Ember.run.schedule("afterRender", () => { ... }); nos permitió depurar el problema real, que en realidad fue un retroceso en el controlador que invoca tanto el componente de visualización de datos como el componente de información sobre herramientas.

tl; dr: No lo guardé allí (también obtuve un error Maximum call stack size exceeded una vez), pero usarlo fue útil para depurar hasta que se descubrió el problema real.

PSA para cualquier otra persona que acaba de actualizar: El error de afirmación mejorado "retroceso re-renderizado" mencionado por @GavinJoyce anteriormente está incluido en Ember 2.11. También se ha sugerido que saltar directamente a 2.11 podría ser útil.

Chicos, necesito ayuda: este error aparece cuando intento usar una propiedad del modelo que "pertenece a" otra. Creé un proyecto en blanco y todavía muestra lo mismo. ¿Qué estoy haciendo mal?

Además, en mi back-end, estoy usando .Net Core con JSON API .Net Core (https://github.com/Research-Institute/json-api-dotnet-core), siguiendo sus instrucciones.

El renderizado de la interfaz de usuario está roto en este punto, sin embargo, los datos se cargan y puedo ver los valores deseados.

    // Profile Model:
    import DS from 'ember-data';
    export default DS.Model.extend({
        'firstName': DS.attr(),
        'lastName': DS.attr(),
        'applicationUser': DS.attr(),
        'contactProfile': DS.belongsTo('address', {
            async: true
        }),
        'companyProfile': DS.belongsTo('address'),
        'companyMailingAddress': DS.belongsTo('address'),
        "companyPhysicalAddress": DS.belongsTo('address')
    });

    // Address Model:
    import DS from 'ember-data';
    export default DS.Model.extend({
        'address1': DS.attr(),
        'address2': DS.attr(),
        'city': DS.attr(),
        'state': DS.attr(),
        'zipCode': DS.attr(),
        'country': DS.attr(),
        'website': DS.attr(),
        'phoneNumber1': DS.attr(),
        'phoneExtension1': DS.attr(),
        'phoneNumber2': DS.attr(),
        'phoneExtension2': DS.attr(),
        'email': DS.attr(),
    });
    // Adapter settings
    import DS from 'ember-data';

    export default DS.JSONAPIAdapter.extend({
        namespace: 'api/json',
    });
    DS.JSONAPISerializer.reopen({
        keyForAttribute(key) {
            return key;
        },
        keyForRelationship(key) {
            return key;
        }
    });
    // Route
    import Ember from 'ember';

    export default Ember.Route.extend({
        model() {
            return Ember.RSVP.hash({
                profile: this.store.findRecord('profile', 1)
            });
        }
    });

    // Template
   {{model.profile.contactProfile.address1}}

y el error me sale:
Error de afirmación: modificó "model.profile.contactProfile" dos veces el@model: profile :: ember543: 1> en un solo render. Fue renderizado en " template: fuels-ember / internal / profile / template.hbs " y modificado en " template: fuels-ember / internal / profile / template.hbs ". Esto no era confiable y lento en Ember 1.xy ya no es compatible. Consulte https://github.com/emberjs/ember.js/issues/13948 para obtener más detalles.

PD: He intentado usar el método Ember.computed para obtener la propiedad, y parece funcionar. ¿Es esto necesario?

Actualización: también descubrí que los datos se cargan bien dentro de un ayudante {{#each}}, pero no directamente en la plantilla.

@lbarsukov
Tal vez esté relacionado con https://github.com/emberjs/data/issues/5023 donde una re-renderización con retroceso es causada por relaciones en su respuesta jsonapi que tiene un conjunto de propiedades links .

Este fue el problema para mí, que comenzó después de Ember Data 2.13.2. Intente usar ember-data: 2.13.2 para ver si esto resuelve su problema.

@ daniel-de-wit Aprobado por el maestro aquí, esto realmente funciona. Ahora hace lo que necesito que haga y estoy contento con él.

@lbarsukov @ daniel-de-wit Hemos lanzado una nueva versión de datos de ember que soluciona este problema.

@lbarsukov Creo que esto tiene que ver con tus relaciones definidas. Es muy probable que uno (o algunos) de los belongsTo sea ​​un hasMany .

Digamos que tiene dos modelos, Pregunta y Respuesta. Si devuelve 10 respuestas a la pregunta, pero cada serializador de preguntas hace referencia a su respuesta, _debe_ definir la relación correctamente.

// Question Model:
    export default DS.Model.extend({
        'answers': DS.hasMany('answers'), // if you never reference question.answers you can omit this
        ...
    });

// Answer Model:
    export default DS.Model.extend({
        'question': DS.belongsTo('question'),
        ...
    });

Cuando los datos se encuentran definiendo múltiples pares de preguntas / respuestas, esperando una relación 1-1 donde no la hay, se infiere que la pregunta se modificó en el medio del procesamiento.

Desde la publicación inicial, se mencionaron algunos ganchos:

Este es un ejemplo bastante extremo, pero ilustra el problema. Además de init, didInitAttrs, didReceiveAttrs, willInsertElement y willRender también ocurren sincrónicamente durante el proceso de renderizado. Además, el retroceso es a menudo un problema que surge del comportamiento de las propiedades enlazadas bidireccionales.

¿Por qué los ganchos didInsertElement y didRender funcionan a la perfección pero los otros ganchos fallan con el error twice render ?

@BenjaminHorn @ Blackening999 @Dhaulagiri @DingoEatingFuzz @ Gaurav0 @GavinJoyce @Redsandro @TRMW @ Turbo87 @aklkv @alidcastano @backspace @bdiz @bgentry @bjornharrtell @bryanhickerson @buschtoens @caseklim @cbou @chancancode @danaoira @fivetanley @ Daniel-de-ingenio @fotinakis @gabrielgrant @ghost @jakesjews @janmisek @joukevandermaas es esto todavía un problema, tal vez deberíamos cerrar, ¿qué piensas?

Solucioné cualquier instancia del error en mi aplicación.

Cada vez que me he encontrado con esto, he podido reorganizar las cosas para que no vuelva a suceder, así que creo que está bien cerrar.

Si, por favor cierre

fin de una era 😬

👍

Lamento mencionar un problema antiguo.

Digamos, por ejemplo, que estoy renderizando

{{this.myBool}}

y el error es Error: Assertion Failed: You modified "myBool" twice

Puedo corregir el error cambiándolo a:

{{if this.myBool true false}}

Del mismo modo, si un enlace de nombre de clase está causando el problema

Puedo cambiar:

classNameBindings: ['myBool']

para

classNameBindings: ['myBool:yes:no']

Si puedo silenciar la advertencia de esta manera, ¿por qué Ember no puede manejarla por mí?

Aquí está el código de demostración que estaba usando:

https://ember-twiddle.com/db7f6e382bd0b1de91447881eebb62a5?openFiles=templates.components.my-component.hbs%2C

Ninguna de esas cosas "soluciona" el problema. O es que cambió al modo de producción o hay errores en el código de aserción / detección. En cualquier caso, debe arreglar el lado que asigna / establece el valor, no el lado que lo consume.

Está bien. Gracias. Entiendo el problema de retroceso descrito en esta publicación original porque tiene un set explícito

Pero en mi juego de demostración, no hay set por lo que puedo ver.

_Editar_ Eso salió mal, quiero decir que no hay set provenientes de una _subsequent_ parte de la plantilla como en el ejemplo

Hm, no obtengo el error en el twiddle, ¿cuál es la secuencia de clics que debo hacer?

Haga clic en abrir y luego en cerrar. Pero el botón de cierre del componente secundario generado, no el principal.

Ya veo, el problema es que durante el desmontaje, se llama a focusOut en el componente que llama a set en una propiedad ya renderizada. No estoy 100% seguro de cómo el componente pierde el foco y la semántica de tiempo. Estoy bastante seguro de que las variaciones que probaste confunden el sistema de seguimiento y enmascaran el problema subyacente. ¿Vamos a rastrear esto en un nuevo número? No estoy seguro de si es un problema válido, pero investiguemos allí.

¿Fue útil esta página
0 / 5 - 0 calificaciones