0

我有大量的knockout組件,它們當前正在使用KO.postbox進行通信。ES2015 Knockout.js組件的Singleton或服務提供商或模塊

我現在想創建一個集中存儲數據的中央服務提供程序/存儲庫/單例,併爲所有這些組件提供初始化和api等功能。

頁面只有一個窗口/會話,但每個頁面都有3-7個Knockout組件,在某些情況下,頁面上會多次加載相同的組件。結果是通過API加載數據的組件和那些也需要相同數據的組件之間存在很多喋喋不休的結果。

我目前的做法是使用單例模式(其他方法愉快考慮)。唯一的不可更改的要求是:

  1. 商店和多個KO組件檢索一箇中央「資料庫」數據
  2. 寫在ES2015和能夠與巴貝爾
  3. 可裝載工作,並導出爲一個模塊

與當前代碼的問題是

一個。這被設置爲babel未定義,例如, this.instance = null產生無法設置未定義實例的錯誤。 b。我真的不知道這是最好的方法,或者,我可以讓它工作

的代碼如下

const ko = require('knockout') 
    , moment = require('moment') 
    , postbox = require('knockout-postbox') 
    , aja = require('aja'); 


const myServiceSingleton =() =>{ 

    this.instance = null; 
    this.array1 = ko.observable([]); 
    this.array2 = ko.observable([]); 

    // revealing module pattern that handles initialization of our new singleton service provider 
    const initializeNewModule =() => { 

     const setArray1 = (array) => { 
      console.info('Set Array1 Called'); 
      this.array1(array); 
     }; 

     const getArray1 =() => { 
      console.info('Get Array1 Called'); 
      return this.array1(); 
     }; 

     const setArray2 = (array) => { 
      console.info('Set Array2 Called'); 
      this.array2(array); 
     }; 

     const getArray2 =() => { 
      console.info('Get Array2 Called'); 
      return this.array2(); 
     }; 

     const myAwesomeFunction =() => { 
      // Perform some amazing computations on Array1 and Array 2 
     }; 

     return { 
      setArray1 : setArray1, 
      getArray1 : getArray1, 
      setArray2 : setArray2, 
      getArray2 : getArray2, 
      myAwesomeFunction : myAwesomeFunction 
     }; 
    }; 

    // handles the prevention of additional instantiations 
    const getInstance =() => { 
     if(! this.instance) { 
      this.instance = new initializeNewModule(); 
     } 
     return this.instance; 
    }; 

    return { 
     getInstance : getInstance 
    }; 

}; 
module.exports = myServiceSingleton; 

--------- --------編輯 -

在希望這有助於別人......

const ko = require('knockout') 
    , moment = require('moment') 
    , postbox = require('knockout-postbox') 
    , aja = require('aja'); 

const array1 = ko.observable([]); 
const array2 = ko.observable([]); 
const secretFlag = ko.observable(false); 

const myAmazingSingleton = { 

    setArray1(newArray) { 
     console.info(newArray); 
     array1(newArray); 
    }, 

    getArray1() { 
     console.info('Get Array1 Called'); 
     return array1(); 
    }, 

    getArray2() { 
     return array2(); 
    }, 

    setArray2(newArray) { 
     console.info('Set Array2 Called'); 
     array2(newArray); 
    }, 

    getArray1Observable() { 
     return array1 ; 
    }, 

    myAwesomeFunction() { 
     // Perform some amazing computations on Array1 and Array 2 
     array1.map //etc etc 
    } 
}; 

export default myAmazingSingleton ; 

要使用非常簡單:

import ArrayFunctions from 'myAmazingSingleton'; 
let array1 = ArrayFunctions.getArray1(); 

而且數據可用於多個Knockout組件

+0

'()=> {//不是一個箭頭函數' - 嗯? – Bergi

+0

忽略評論 - 這是一箇舊的代碼,我忘了整理:) – brianlmerritt

回答

1

您不能使用箭頭函數作爲構造函數。你真的應該只使用一個簡單的對象文字:

const myServiceSingleton = { 
    array1: ko.observable([]), 
    array2: ko.observable([]), 
    setArray1(array) { 
     console.info('Set Array1 Called'); 
     this.array1(array); 
    }, 
    getArray1() { 
     console.info('Get Array1 Called'); 
     return this.array1(); 
    }, 
    setArray2(array) { 
     console.info('Set Array2 Called'); 
     this.array2(array); 
    }, 
    getArray2() { 
     console.info('Get Array2 Called'); 
     return this.array2(); 
    }, 
    myAwesomeFunction() { 
     // Perform some amazing computations on Array1 and Array 2 
    } 
}; 

如果你堅持,你可以做一個

export function getInstance() { 
    return myServiceSingleton; 
} 

甚至懶惰初始化,但通常你應該只是export default它。

+0

假定array1和array2都是公開的,所以不必調用'myServiceSingleton.getArray1( )'我或者團隊中的任何其他人都可以使用'myServiceSingleton.array1()'。所以對象文字應該可以工作,但是什麼是使數據保密的好方法? – brianlmerritt

+0

導入myServiceSingleton對象文本可以在KO組件中使用,但每個導入似乎都會引入它自己的新版本而不是單例。我正在使用'export {myServiceSingleton}'和'myServiceSingleton'導入{myServiceSingleton}。例如'myServiceSingleton.array1.subscribe'從不觸發。這是否應該發生?我有Babel/Browserify設置錯誤嗎? – brianlmerritt

+0

如果您想讓數據保密,只需使用本地變量(在模塊級別)。當然,你不能使用'this.arrayN()'。 – Bergi

1

我認爲您想使用的單例是一個主視圖模型,我的意思是設置Knockout的常用方法。使用組件'params從主視圖模型傳遞組件需要共享的任何可觀察對象。

+0

我相信你是對的,如果我不使用多個頁面上的代碼或至少可以在這些多個頁面上使用相同的主視圖模型。但是如果我需要其他視圖模型的功能(或其一部分),那麼這會使決策變得更加困難。非常感謝您快速回來,我會考慮通過:) – brianlmerritt

+0

需要重新使用的任何代碼都可以作爲其應用程序的主視圖模型將導入的其自己的模塊。主VM仍然會處理傳遞相關位到組件。 –

+0

我選擇了對象字面模式,但是也勾選了您的答案,因爲我可以將其用於每個充當SPA的頁面 – brianlmerritt