我正在执行一项任务,需要将搜索字段连接到一个简单的JS应用程序,该应用程序显示一些项目,用户可以搜索并过滤它们。
共有三类-App,ProductsPanel和Search。 Search和ProductsPanel都在App类内部进行了初始化。
ProductsPanel类包含一个包含10个产品的数组。
我想从Search内部调用ProductsPanel的方法来过滤产品。我怎样才能做到这一点?
我尝试在第一个类的构造函数中使用this.productsPanel = new productsPanel(),但这会带来一个没有所有产品数组的新实例。
这是App类:
class App {
constructor() {
this.modules = {
search: {
type: Search,
instance: null
},
filter: {
type: Filter,
instance: null
},
productsPanel: {
type: ProductsPanel,
instance: null
},
shoppingCart: {
type: ShoppingCart,
instance: null
}
};
}
init() {
const placeholders = document.querySelectorAll("#root [data-module]");
for (let i = 0; i < placeholders.length; i++) {
const root = placeholders[i];
const id = root.dataset.module;
const module = this.modules[id];
if (module.instance) {
throw new Error(`module ${id} has already been started`);
}
module.instance = new module.type(root);
module.instance.init();
// console.info(`${id} is running...`);
}
}
}
app = new App();
app.init();
这是搜索:
export default class Search {
constructor(root) {
this.input = root.querySelector("#search-input");
}
// addEventListener is an anonymous function that encapsulates code that sends paramaters to handleSearch() which actually handles the event
init() {
this.input.addEventListener("input", () => {
this.handleSearch();
});
}
handleSearch() {
const query = this.input.value;
app.modules.productsPanel.instance.performSearch(query);
}
}
和ProductsPanel类:
export default class ProductsPanel {
constructor(root) {
this.view = new ProductsPanelView(root, this);
this.products = [];
}
init() {
this.products = new ProductsService().products;
this.products.forEach(x => this.view.addProduct(x));
}
performSearch(query) {
query = query.toLowerCase();
this.products.forEach(p => {
if (query === p.name) {
this.view.showProduct(p.id);
} else {
this.view.hideProduct(p.id);
}
});
}
addToCart(id) {
const product = this.products.filter(p => p.id === id)[0];
if (product) {
app.modules.shoppingCart.instance.addProduct(product);
}
}
}
我想在由App类创建的实例上调用ProductsPanel的performSearch方法。我不知道该怎么做。
答案 0 :(得分:0)
尝试下面的自定义事件处理程序类
class CustomEventEmitter {
constructor() {
this.eventsObj = {};
}
emit(eName, data) {
const event = this.eventsObj[eName];
if( event ) {
event.forEach(fn => {
fn.call(null, data);
});
}
}
subscribe(eName, fn) {
if(!this.eventsObj[eName]) {
this.eventsObj[eName] = [];
}
this.eventsObj[eName].push(fn);
return () => {
this.eventsObj[eName] = this.events[eName].filter(eventFn => fn !== eventFn);
}
}
}
如何使用?
创建CustomEventEmitter
类的对象
let eventEmitter = new CustomEventEmitter()
订阅活动
emitter.subscribe('event: do-action', data => {
console.log(data.message);
});
致电事件
emitter.emit('event: do-action',{message: 'My Custom Event handling'});
希望这会有所帮助!