2017-05-19 18 views
5

Jestem próbujących budować podstawowe wtyczki JS, które można nazwać po zdarzeniu kliknięcia przycisku, aby wyłączyć (aby uniemożliwić użytkownikom odpalane wiele wywołań API) i wyrazić opinię, że coś jest ładowanie/happening. Oto jak to wygląda:Podstawowe ES6 JavaScript Plugin - ponowne zmienny między funkcjami

enter image description here

Działa to doskonale na zasadzie indywidualnej, ale chcę, aby ponownie zapisać go jako plugin więc mogę używać go po drugiej stronie.

Oto obniżyć wersja JS od loader.plugin.js plików.

let originalBtnText; 


export function showBtnLoader(btn, loadingText) { 
    const clickedBtn = btn; 
    const spinner = document.createElement('div'); 

    spinner.classList.add('spin-loader'); 

    originalBtnText = clickedBtn.textContent; 
    clickedBtn.textContent = loadingText; 
    clickedBtn.appendChild(spinner); 
    clickedBtn.setAttribute('disabled', true); 
    clickedBtn.classList.add('loading'); 

    return this; 
} 


export function hideBtnLoader(btn) { 
    const clickedBtn = btn.target; 
    clickedBtn.textContent = originalBtnText; 
    clickedBtn.removeAttribute('disabled'); 
    clickedBtn.classList.remove('loading'); 

    return this; 
} 


export function btnLoader() { 
    showBtnLoader(); 
    hideBtnLoader(); 
} 

Oto przykład tego, jak chciałbym go użyć.

import btnLoader from 'loaderPlugin'; 

const signupBtn = document.getElementById('signup-btn'); 

signupBtn.addEventListener('click', function(e) { 
    e.preventDefault(); 
    btnLoader.showBtnLoader(signupBtn, 'Validating'); 
    // Call API here 
}); 

// Following API response 
hideBtnLoader(signupBtn); 

Problem mam jest, że chcę, aby zapisać originalBtnText z funkcji showBtnLoader a następnie użyć tej zmiennej w funkcji hideBtnLoader. Mogłem oczywiście osiągnąć to w inny sposób (np. Dodając wartość jako atrybut danych i chwytając go później), ale zastanawiałem się, czy istnieje prosty sposób.

Kolejna kwestia to fakt, że nie wiem prawidłowy sposób wywoływania poszczególnych funkcji i czy jestem importowania go prawidłowo. Próbowałem następujące.

btnLoader.showBtnLoader(signupBtn, 'Validating'); 
btnLoader(showBtnLoader(signupBtn, 'Validating')); 
showBtnLoader(signupBtn, 'Validating'); 

Ale pojawia się następujący błąd:

Uncaught ReferenceError: showBtnLoader is not defined 
    at HTMLButtonElement.<anonymous> 

Przeczytałem kilka dobrych artykułów i tak odpowiedzi takie jak http://2ality.com/2014/09/es6-modules-final.html i ES6 export default with multiple functions referring to each other ale jestem lekko zdezorientowana co do „poprawny” sposób prowadzenia tak, aby można go było ponownie wykorzystać.

Wszelkie wskazówki będą mile widziane.

+0

Zaimportuj je w nawiasach klamrowych ze strony docelowej {element, element} z "./page"; a na stronie docelowej wyeksportuj {item, item} – Ozan

+0

Plugin? W co? – Bergi

+0

, chyba że są "domyślne ustawienia eksportu", musisz je jawnie zaimportować poprzez 'import {showBtnLoader} z 'loaderPlugin';' –

Odpowiedz

2

bym eksport funkcji, która tworzy obiekt z obu pokazywać i ukrywać funkcji, takich jak to:

export default function(btn, loadingText) { 

    function show() { 
    const clickedBtn = btn; 
    const spinner = document.createElement('div'); 

    spinner.classList.add('spin-loader'); 

    originalBtnText = clickedBtn.textContent; 
    clickedBtn.textContent = loadingText; 
    clickedBtn.appendChild(spinner); 
    clickedBtn.setAttribute('disabled', true); 
    clickedBtn.classList.add('loading'); 
    } 

    function hide() { 
    const clickedBtn = btn.target; 
    clickedBtn.textContent = originalBtnText; 
    clickedBtn.removeAttribute('disabled'); 
    clickedBtn.classList.remove('loading'); 
    } 

    return { 
    show, 
    hide, 
    }; 
} 

Następnie, aby go użyć:

import btnLoader from 'btnloader'; 

const signupBtn = document.getElementById('signup-btn'); 
const signupLoader = btnLoader(signupBtn, 'Validating'); 

signupBtn.addEventListener('click', function(e) { 
    e.preventDefault(); 
    signupLoader.show(); 
    // Call API here 
}); 

// Following API response 
signupLoader.hide(); 

Jeśli chcesz ukryć go z innego pliku, z którego pokazał go, a następnie można wyeksportować instancję:

export const signupLoader = btnLoader(signupBtn, 'Validating'); 

A później zaimportować go.

import { signupLoader } from 'signupform'; 

function handleApi() { 
    signupLoader.hide(); 
} 
+0

To naprawdę pomogło. Musiał zadeklarować originalBtnText poza funkcją show i hide, ponieważ jest używany w obu funkcjach, ale poza tym działało dobrze. Dzięki. – GuerillaRadio

+0

Cieszę się, że to wymyśliliście, Pozdrawiam! – coderkevin

1

Być może nadpisujesz element.prototyp, aby był dostępny od tego elementu. Jednak nie pojadę ustawić wartości na tym elemencie, wolałbym wrócić obiektu wraz ze wszystkimi neccessary rzeczy:

export function implementBtnLoader(){ 
Element.prototype.showBtnLoader=function(loadingText) { 
    const clickedBtn = this; 
    const spinner = document.createElement('div'); 

    spinner.classList.add('spin-loader'); 

    var originalBtnText = clickedBtn.textContent; 
    clickedBtn.textContent = loadingText; 
    clickedBtn.appendChild(spinner); 
    clickedBtn.setAttribute('disabled', true); 
    clickedBtn.classList.add('loading'); 

    return { 
     text:originalBtnText, 
     el:this, 
     hideBtnLoader: function() { 
      const clickedBtn = this.target; 
      clickedBtn.textContent = this.text; 
      clickedBtn.removeAttribute('disabled'); 
      clickedBtn.classList.remove('loading'); 
      return this; 
     } 
    }; 
    }; 
} 


export function btnLoader() { 
    implementBtnLoader(); 
} 

Po zaimportowaniu i implementBtnLoader nazwano, można zrobić:

var loader=document.getElementById("test").showBtnLoader(); 
console.log(loader.text); 
loader.hideBtnLoader(); 
+0

Właśnie zaimplementowałem twoje sugestie Jonas, ale teraz otrzymuję komunikat "Uncaught TypeError: clickedBtn.showBtnLoader" funkcja w HTMLButtonElement ". Importuję funkcję za pomocą "import btnLoader from 'loaderPlugin'; ' i próbuje wywołać moduł ładujący za pomocą "clickedBtn.showBtnLoader (" Ładowanie "); (clickedBtn jest celem kliknięcia). – GuerillaRadio

+0

@GuerllillaRadio czy wykonałeś zaimportowaną funkcję? btnLoader(); –

Powiązane problemy