How to prevent $state from refreshing any Componen

2019-04-16 06:59发布

问题:

We're using Angular-ui-router for our app state management.

A problem we're having is that every component refreshes when the $state changes, even if it's a variable that is updated that does not exist/not used in some components.

For example, we have a TickersPanel and a TagsPanel. When a Ticker is selected, the TagsPanel should be updated and refreshed, however when a tag is selected in the TagsPanel, the TickersPanel should NOT refresh, but it currently does.

I found out that { notify: false } is another object that can be passed in. However once I do that, NO components will refresh.

const save = (tag, terms) => {
    CONTAINER.push(tag);
    $state.go('charting', Term.write(terms), { notify: false }).then((stateResult) => {
        console.log('stateResult', stateResult);
    });
};

Has anyone found a way around this problem?


TagsPanel $onInit (Runs on every $state change)

this.$onInit = () => {
    tagsCol.addEventListener('scroll', scrollingTags);

    this.tags = [];
    this.limit = 30;

    const panelOpen = Dashboard.panelStatus(this.tagsOpen, this.chartMax);
    panelOpen ? buildTagList() : collapsePanel();
};

TickersPanel $onInit (Runs on every $state change, if $state.params.ticker did not change, then this should not be ran)

this.$onInit = () => {
    this.tickers = [];

    this.spy = {
        longname: "SPDR S&P 500",
        ticker: "SPY",
    };

    this.showTickersPanel = Dashboard.panelStatus(this.tagsOpen, this.chartMax);
    // const currentState = $state.params;
    // const prevState = Dashboard.getPreviousState();
    loadTickers().then(() => this.loadingTickersDone = true);
};

回答1:

I've made a JsFiddle to describe a way to achieve what I've understood from your question using the uiRouter.

The fiddle uses state inheritance and named views to only reinitialize the tags state when the tickers param changes.

[..]
// Using @ on the view names to refer to the absolute uiViews.
$stateProvider.state('tickers', {
    url: "",
    views: {
      'tickersPanel@': {
        template: [..]
        bindToController: true,
        controllerAs: "$ctrl",
        controller: function() {
          this.$onInit = function() {
            console.info('Tickers Panel $onInit');
            this.tickers = ["Ticker1", "Ticker2", "Ticker3"]
          }
        }
      },
      [..]
    }
});
$stateProvider.state('tags', {
    parent: 'tickers',
    url: "/:ticker",
    views: {
      'tagsPanel@': {
        template: [..]
        controllerAs: '$ctrl',
        bindToController: true,
        controller: function($stateParams) {
          this.$onInit = function() {
            console.info('Tags Panel 2 $onInit');
            this.ticker = $stateParams["ticker"];
          }
        }
      }
    }
});
[..]


回答2:

Why not just maintain the state in your component and return at the beginning of the function if the state hasn't changed?