How to pass data when navigating back


#1

I know how to pass props when using $navigateTo (context / propsData) but am struggling with how to pass data when using $navigateBack. The only sane solution I can think of right now is to create some shared data using vuex but I’d still need to react on some events (are there any fired when navigating between screens?).


#2

Objects are shared by reference, so if you just pass an object in your component to $navigateTo context, when it’s updated, that is already there in the object reference of previous component.

Vuex could be nice if you are already using it.


#3

@manojdcoder interesting. Ok, that makes sense (even if would make code much leas readable than vue standard way of components communication - $emit & v-on combo).

However, I would still somehow need to know when data changes. I can probably bind master component as a “delegate” at detail component and call master’s method at the detail component at the time when “$navigateBack” is called but it would make life easier if I could bind to navigation events somehow. I couldn’t find anything about this at docs, though. Should I create another topic with that question?


#4

Hmm, ok, I’ve tried a delegate pattern but failed: I wanted to extend detail-component with $delegate attribute pointing to main component but it doesn’t seem to work (somehow that attribute is lost after navigation is done).

@manojdcoder can you elaborate what did you mean with object reference? I must have misunderstood what you meant.

BTW, this is the code I’ve tried:

const ColorsSelector = {
  template: `
  <Page>
    <ActionBar title="Colors picker"/>
    <StackLayout>
      <Button
        :style="{ color: color }"
        v-for="color in colors"
        :key="color"
        @tap="selectColor(color)"
        :text="color"
      />
    </StackLayout>
  </Page>
  `,
  data() {
    return {
      colors: ['red', 'blue', 'green']
    }
  },
  methods: {
    selectColor(color) {
      this.$delegate.setColor(color)
      this.$navigateBack()
    }
  }
}

const MainComponent = {
  template: `
  <StackLayout>
    <Button @tap="openColorSelector()" text="Select your favourite color"/>
    <Label v-show="color" :text="color"/>
    <Label v-show="!color" text="Color not selected yet"/>
  </StackLayout>
  `,
  data() {
    return {
      color: null
    }
  },
  methods: {
    openColorSelector() {
      const component = { ...ColorsSelector, $delegate: this }
      this.$navigateTo(component)
    },
    setColor(color) {
      this.color = color
    },
  }
}

and error I’m getting :

file:///app/app.js:58214:21: JS ERROR TypeError: undefined is not an object (evaluating 'this.$delegate.setColor')

#5

That’s what I meant but you are suppose to access the delegate via props as mentioned in the manual routing docs.


#6

Oh, ok, got that. And indeed I’ve overcomplicated this in my previous comment. Updated snippet works properly now:

 ColorsSelector = {
  template: `
  <Page>
    <ActionBar title="Colors picker"/>
    <StackLayout>
      <Button
        :style="{ color: color }"
        v-for="color in colors"
        :key="color"
        @tap="selectColor(color)"
        :text="color"
      />
    </StackLayout>
  </Page>
  `,
  props: ['$delegate'],
  data() {
    return {
      colors: ['red', 'blue', 'green']
    }
  },
  methods: {
    selectColor(color) {
      this.$delegate.setColor(color)
      this.$navigateBack()
    }
  }
}

const MainComponent = {
  template: `
  <StackLayout>
    <Button @tap="openColorSelector()" text="Select your favourite color"/>
    <Label v-show="color" :text="color"/>
    <Label v-show="!color" text="Color not selected yet"/>
  </StackLayout>
  `,
  data() {
    return {
      color: null
    }
  },
  methods: {
    openColorSelector() {
      this.$navigateTo(ColorsSelector, { context: { propsData: { $delegate: this } } })
    },
    setColor(color) {
      this.color = color
    },
  }
}

Thanks!