En JavaScript , las llamadas a métodos encadenados son muy populares, y los amigos que usan jQuery deben tener un conocimiento profundo de esto. Este método se describe con más detalle en "Patrones de diseño de Javascript". Para implementar llamadas en cadena a métodos, solo necesita dejar que los métodos definidos en el prototipo devuelvan referencias a los objetos de instancia que llaman a estos métodos. Consulte el libro This. código:
(función() {
función _$(els) {
this.elementos = [];
for (var i = 0, len = els.length; i < len; ++i) {
elemento var = els[i];
if (tipo de elemento == 'cadena') {
elemento = document.getElementById(elemento);
}
this.elements.push(elemento);
}
};
_$.prototipo = {
cada uno: función(función) {
for ( var i = 0, len = this.elements.length; i < len; ++i ) {
fn.call(esto, esto.elementos[i]);
}
devolver esto;
},
setStyle: función (prop, val) {
this.each(función(el) {
el.estilo[prop] = val;
});
devolver esto;
},
mostrar: función() {
var eso = esto;
this.each(función(el) {
that.setStyle('mostrar', 'bloquear');
});
devolver esto;
},
addEvent: función (tipo, fn) {
var agregar = función(el) {
si (ventana.addEventListener) {
el.addEventListener(tipo, fn, falso);
}
de lo contrario si (ventana.attachEvent) {
el.attachEvent('on'+tipo, fn);
}
};
this.each(función(el) {
agregar(el);
});
devolver esto;
}
};
ventana.$ = función() {
devolver nuevo _$(argumentos);
};
})();
Como puede ver, cada método termina con "return this", que pasa el objeto del método que llama al siguiente método de la cadena. Sin embargo, si los datos que queremos operar se obtienen mediante una solicitud asincrónica, ¿cómo mantener la cadena de llamadas a métodos? Dustin Diaz nos proporciona una forma de garantizar llamadas a métodos encadenados. También es uno de los autores del libro "Patrones de diseño de JavaScript".
Primero construyó un objeto Cola, a saber:
Luego utilícelo como herramienta para construir nuestra cadena de cola de métodos asincrónicos. Con esta herramienta, es fácil crear un complemento jQuery que obtenga contenido del servidor y lo agregue a un selector.
De esta forma podremos obtener el contenido de forma asincrónica y continuar nuestra cadena de llamadas.
$("<div/>")
.fetch('/servidor/navegación.html')
.addClass('columna')
.appendTo('#lado');
Consulte la página de demostración para ver el efecto.
¿Qué hacer si hay muchos elementos en una cola esperando a que se actúe en una respuesta del lado del servidor? El autor construyó un método de este tipo, al que vale la pena hacer referencia:
De esta forma, podemos llamarlo de la siguiente manera:
fetchTweet(url).linkify().filterBadWords().appendTo('#status');
En este punto, ya sabemos cómo implementar el encadenamiento de métodos asincrónicos, pero vale la pena pensar en algunas preguntas planteadas por algunos comentarios al final de " Encadenamiento de colas de métodos asincrónicos en JavaScript ". El complemento $.fn.fetch solo necesita agregar el contenido devuelto al elemento. ¿Es necesaria la cola? Además, $.fn.load en jQuery se puede implementar completamente. Si solo se usa una función de devolución de llamada en la cola, se puede escribir así:
(función ($) {
$.fn.fetch = función(url) {
cola var = nueva cola;
this.each(función() {
var el = esto;
$.ajax({
URL: URL,
tipo: 'obtener',
tipo de datos: 'json',
éxito: función (resp) {
$(el).html(resp['text1']);
}
});
});
devolver esto;
};
})(jQuery);
¿Me pregunto qué piensas?
función fetchTweet(url) {
this.queue = nueva cola;
este.tweet = "";
var self = esto;
ajax(url, función(resp) {
self.tweet = resp;
self.queue.flush(esto);
});
}
fetchTweet.prototipo = {
vincular: función() {
this.queue.add(función(auto) {
self.tweet = self.tweet.replace(/b@(w{1,20}b/g, '$1');
});
devolver esto;
},
filtrarPalabrasMalas: función() {
this.queue.add(función(auto) {
self.tweet = self.tweet.replace(/b(joder|mierda|mear)b/g, "");
});
devolver esto;
},
agregar a: función (selector) {
this.queue.add(función(auto) {
$(self.tweet).appendTo(selector);
});
devolver esto;
}
};
(función ($) {
$.fn.fetch = función(url) {
cola var = nueva cola;
this.each(función() {
var el = esto;
cola.add(función(resp) {
$(el).html(resp);
});
});
$.ajax({
URL: URL,
tipo de datos: 'html',
éxito: función (html) {
cola.flush(html);
}
});
devolver esto;
};
})(jQuery);
función Cola() {
// almacena tus devoluciones de llamada
this._methods = [];
// mantenemos una referencia a tu respuesta
this._response = nulo;
// todas las colas comienzan sin vaciar
this._flushed = falso;
}
Cola.prototipo = {
// agrega devoluciones de llamada a tu cola
agregar: función (función) {
// si la cola se ha vaciado, regresa inmediatamente
si (this._flushed) {
fn(this._response);
// de lo contrario, lo ponemos en la cola
} demás {
this._methods.push(fn);
}
},
color: función(resp) {
// nota: el lavado sólo ocurre una vez
si (this._flushed) {
devolver;
}
// almacena tu respuesta para llamadas posteriores después de descarga()
this._response = resp;
// marca que ha sido lavado
this._flushed = verdadero;
// sácalos y llámalos de vuelta
mientras (this._methods[0]) {
this._methods.shift()(resp);
}
}
};