Búsqueda de sitios web

angular - Asignando noop a una variable


Estaba investigando el código fuente de las utilidades de Angular y acabo de encontrar la siguiente línea:

export const NOOP: any = () => {};

Bueno, lo anterior es bastante obvio. Declara una variable que no haga ninguna operación. Ahora, dentro de la misma biblioteca tengo el siguiente método:

export function resolveViewDefinition(factory: ViewDefinitionFactory): ViewDefinition {
  let value: ViewDefinition = VIEW_DEFINITION_CACHE.get(factory) !;
  if (!value) {
    value = factory(() => NOOP);
    value.factory = factory;
    VIEW_DEFINITION_CACHE.set(factory, value);
  }
  return value;
}

¿Cuál sería el efecto de simplemente no tener esa línea en su lugar y comentarla, y tener el bloque de la siguiente manera:

  if (!value) {
    // value = factory(() => NOOP);
    value.factory = factory;
    VIEW_DEFINITION_CACHE.set(factory, value);
  }

¿Alguien podría elaborar más sobre esta línea:

value = factory(() => NOOP);

¿y arrojar más luz sobre ello? Puedo ver lo que está pasando, pero no puedo entender los efectos de eliminarlo.

Respuesta #1

La función resolveViewDefinition se utiliza para obtener la definición de vista. Primero intenta obtener el value de la caché y, si no hay un valor en caché, entonces llama a ViewDefinitionFactory.

ViewDefinitionFactory toma una función como parámetro. ¿Por qué?

/**
 * Factory for ViewDefinitions.
 * We use a function so we can reexecute it in case an error happens and use the given logger
 * function to log the error from the definition of the node, which is shown in all browser
 * logs.
 */
export interface ViewDefinitionFactory { (logger: NodeLogger): ViewDefinition; }

No necesitamos registrar errores cuando solo estamos obteniendo ViewDefinition, por lo que se llama con la función NOOP.

Pero cuando obtenemos un error al ejecutar alguna acción dentro de la plantilla, Angular está ejecutando esta fábrica con NodeLogger para determinar qué nodo causó el error.

Veamos el ejemplo Plunker

@Component({
  selector: 'my-app',
  template: `<h2 (click)="x()">Hello</h2>`
})
export class App {}

Aquí está la fábrica

function View_App_0(l) {
  return jit_viewDef1(0,[
      (l()(),jit_elementDef2(0,null,null,1,'h2',[],null,[[
        null,
        'click'
      ]
    ],function(v,en,$event) {
      var ad = true;
      var co = v.component;
      if (('click' === en)) {
        var pd_0 = (co.x() !== false);
        ad = (pd_0 && ad);
      }
      return ad;
    },null,null)),
    (l()(),jit_textDef3(null,['Hello']))
  ]
  ,null,null);
}

1) Aplicación en ejecución

function resolveViewDefinition(factory) {
    var value = ((VIEW_DEFINITION_CACHE.get(factory))); // we haven't cached it yet 
    if (!value) { // value is undefined 
        value = factory(function () { return NOOP; }); //get ViewDefinition but do not log errors
        value.factory = factory; // save link to the factory so it can be used later
        VIEW_DEFINITION_CACHE.set(factory, value); // store factory
    }
    return value;
}

2) Después de hacer clic en Hello

((logViewDef.factory))(nodeLogger); // use saved link to call factory with logger