2016-04-11 19 views
5

Se sei in una grande base di codici angolari 1 e non vuoi introdurre nuove dipendenze (come ngRedux), sarebbe una pessima idea iniziare a utilizzare le funzioni classiche di Angular 1, come $ rootScope, $ broadcast, $ on, $ guarda per implementare un'architettura simile a quella di Redux?

Il mio modo di vedere, potrebbe essere fatto come segue:

  • per la memorizzazione/modello -> Usa $rootScope
  • Per store.dispatch(ACTION) -> Usa $rootScope.$broadcast(ACTION)
  • Riduttori sarebbero implementate come servizi iniettando $rootScope e facendo $on(ACTION)
  • I controllori potevano controllare le modifiche su $rootScope con $watch e aggiornare la vista o le viste potrebbero vincolare direttamente al $rootScope proprietà

Finché si sta disciplinato per non fare strane mutazioni out-of-luogo il $rootScope proprietà, mantenere tutte logica dell'applicazione nei riduttori e mantenere il codice controller al minimo, il più grande svantaggio che può vedere con questo sta avendo prestazioni terribili a causa di costosi cicli digest di Angular 1. Ma se si può anche attenersi alle strutture di dati immutabili , potrebbe non essere nemmeno il caso.

Questa è una cattiva idea? Qualcuno ha provato questo?

risposta

7

Naturalmente, puoi fare il tuo lavoro usando solo $rootScope. Ma ha molti altri scopi che interferiranno con il tuo stato.

Vediamo:

// reducer-like 
$rootScope.$on('COUNTER_INCREMENT', (e, action) => { 
    //I don't use += to emphase immutability of count property; 
    $rootScope.count = $rootScope.count + action.value; 
}); 

//action-ish creator 
$rootScope.$broadcast('COUNTER_INCREMENT', {value: 5}); 

//store subscribe-like 
$rootScope.$watch('count', (count) => { 
    //update something in your component 
}) 

si può fare se si vuole, ma si vede c'è un problema con l'immutabilità poco chiaro. È molto difficile controllare che il tuo gestore di azioni sia puro, perché in realtà non lo è.

Non esiste un gestore azioni predefinito, non è possibile impostare uno stato iniziale di archiviazione semplice. E usi ancora $watch e digesti che probabilmente vorrai evitare.

Inoltre, non è possibile iscriversi a tutti gli aggiornamenti, non esiste un unico punto di reset, tutto come Redux lo fa con cose che viaggiano nel tempo.

Se si desidera continuare a utilizzare Redux come pattern, probabilmente si finirà con alcuni helper che renderanno il codice più simile a Redux.

Beh, perché non iniziare a usare Redux da un semplice servizio di utilità angolare:

angular.module('app', []).factory('store',() => { 
    //if you have many reducers, they should be as separate modules, and imported here 
    function counter(state = 0, action) { 
    switch (action.type) { 
     case 'INCREMENT': 
     return state + action.value; 
     default: 
     return state; 
    } 
    } 

    // here you can add here middlewares that make Redux so powerful 
    return Redux.createStore(counter); 
}); 

Qui andiamo. Ora è possibile utilizzare il servizio di archivio per le azioni

angular.module('app').controller('MyController', ($scope, store) => { 
    store.subscribe(() => { 
    //you may not to care about $scope.$digest, if your action was triggered within angular scope as well 
    $scope.count = store.getState(); 
    }); 

    $scope.onClick =() => store.dispatch({type: 'INCREMENT', value: 1}); 
}); 

Ora avete una messa a punto adeguata, in cui i vostri abbonati non conoscono l'azione che è stato causato invio, la vostra creazione azione e azione riducente logica completamente indipendente come richiesto dalla Modello Redux.

Problemi correlati