2017-05-19 15 views
5

ボタンを無効にするクリックイベントの後に呼び出すことができる基本的なJSプラグインをビルドしようとしています(ユーザーが複数のAPI呼び出しを呼び出さないようにする)ロード/起きる。ここでは、それがどのように見えるかです:Basic ES6 Javascript Plugin - 関数間で変数を再利用

enter image description here

これは、個別に素晴らしい作品が、私はそう、私はサイト全体でそれを再利用することができますプラグインとして書き直すことにしたいです。

ファイルloader.plugin.jsからのJSの縮小版です。

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(); 
} 

これはどのように使用したいかの例です。

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); 

私が持っている問題は、私がshowBtnLoader関数からoriginalBtnTextを格納し、hideBtnLoader関数内でその変数を使用したいということです。もちろん、これを別の方法(データ属性として値を追加して後で取得するなど)で達成することはできますが、単純な方法があるかどうかは疑問です。

私が持っているもう一つの問題は、個々の機能を呼び出す正しい方法と、正しくインポートするかどうかがわからないことです。私は以下を試した。

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

しかし、私は次のエラーを取得する:

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

私はいくつかの良い記事や、このようなhttp://2ality.com/2014/09/es6-modules-final.htmlES6 export default with multiple functions referring to each otherとしてSOの回答を読みましたが、私がやっての「正しい」方法に関しては少し混乱していますこれを再利用可能にする。

いずれのポインタも大歓迎です。

+0

「./page」のターゲットページ{item、item}から中かっこでインポートします。ターゲットページのエクスポート{item、item} – Ozan

+0

プラグイン?何に? – Bergi

+0

'export default'でなければ、 'loaderPlugin'から' import {showBtnLoader} 'を使って明示的にインポートする必要があります; –

答えて

2

私は希望このように、ショーと非表示の両方の機能を持つオブジェクトを作成する関数をエクスポート:

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, 
    }; 
} 

次に、それを使用する:

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(); 

あなたは、あなたがそれを示した場所とは異なるファイルからそれを非表示にする必要がある場合は、インスタンスをエクスポートすることができます。

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

、後でそれをインポートします。

import { signupLoader } from 'signupform'; 

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

これは本当に助けになりました。両方の機能で使用されているように、showButtonTextをshowとhideの外で宣言しなければならなかったが、それ以外はうまくいきました。ありがとう。 – GuerillaRadio

+0

うれしいことが分かりました、乾杯! – coderkevin

1

Element.prototypeをオーバーライドして、その要素から直接アクセスできるようにすることができます。しかし、私はその要素に値を設定するwouldntは、私はむしろ、すべてのneccessaryのものを持つオブジェクトを返します:

輸入、およびimplementBtnLoaderが呼び出された
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(); 
} 

は、1が行うことができます:

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

あなたの提案を実装しましたが、今は' Uncaught TypeError:clickedBtn.showBtnLoaderがありませんHTMLButtonElementの関数です。 '私は関数を 'import btnLoader from' loaderPlugin ';を使用してインポートしています。 'clickedBtn.showBtnLoader(' Loading ');'を使用してローダーを呼び出そうとしました。 (clickedBtnはクリックターゲットです)。 – GuerillaRadio

+0

@GuerllillaRadioあなたはインポートされた関数を実行しましたか? btnLoader(); –

関連する問題