mautilus / sdk

MAUTILUS SmartTV SDK
BSD 3-Clause "New" or "Revised" License
98 stars 43 forks source link

any method will be invoked when Router.goBack() ? #22

Closed kingctan closed 8 years ago

kingctan commented 8 years ago

any method will be invoked when Router.goBack? for example, 1.scene A ----> scene B. then 2.scene B ----->goback----->scene A, how about b's method and a's method will both be invoked in 2. and how to pass parameters to goback method? Thanks.

radimbuchtela commented 8 years ago

Hi, unfortunately method Router.goBack() doesn't provide possibility to pass the parameter.

Maybe there can be helpful to use method Scene.onBeforeGoBack(activeSceneName) which is fired after Router.goBack(). It has just one parameter activeSceneName - name of scene from which it is returned.

1) I see chance to modify Router.goBack() method so

// core/module/Router.js
// http://smarttv.mautilus.com/SDK/source/router.html#Router-method-goBack
/**
* Routes to the previous scene
*/
goBack: function(myParameter) {
    ...
    if (returnScene) returnScene.onBeforeGoBack(this.activeSceneName, myParameter);
    ...
}
// MyScene.js
/**
*  It is fired on call Router.goBack()
*/
onBeforeGoBack: function(activeSceneName, myParameter) {
    // process myParameter inside scene
}

then you can call

Router.goBack(myParameter);

Of course this modification above is not recommended due modification core library ;)

2) Or next possibillity is to put myParameter to Router.history so

var myParameter;
//Router.history[0] - keeps current scene parameters
//Router.history[1] - keeps previous scene parameters  
Router.history[1].push(myParameter);   // pass myParameter
Router.goBack();

// myScene.js
activate: function(..., myParameter) {
    // process myParameter inside scene
}

Radim

SoCoxx commented 8 years ago

There are several methods called while Router.goBack() as well as by Router.go() and there are 2 scenarions.

  1. Scenario - going from one scene to different scene

    Router.go("sceneA", {}) -> Router.go("sceneB", {}) -> Router.goBack()

    Method flow is following:

    Scene.deactivate(); Called still on active scene before going back. Returning Promise here, you can hold on this and after resolving the promise, process will set (CSS style="display:none") and continue to next method. Can't imagine a situation that will require postponing this method with Promise, but it is there. Returning nothing or something else than Promise will cause no block.

    Scene.activate(); This is called after showing new scene. Returning Promise here, you can hold on this (scene has CSS style="display:block"). For example data needs to be fetched via asynchronous call. After resolving the promise, process will continue to next method. Returning nothing or something else than Promise will cause no block.

    Scene.render(); Called after activate(). It should be used for generating content into DOM

    Scene.focus(); Called after render(). It should be used to manage default focus on scene. In most cases it is just delegation to one of the scene snippet: snippetObject.focus().

  2. Scenario - going from one scene to the same scene with different params

    Router.go("sceneA", {}) -> Router.go("sceneA", {})

    Here, no scene is being deactivated/activated and nothing is pushed to history, so you can't goBack(). Method flow is following:

    Scene.refresh(); Called after go().

    Scene.focus(); Called after refresh(). It should be used to manage default focus on scene. In most cases it is just delegation to one of the scene snippet: snippetObject.focus().

radimbuchtela commented 8 years ago

If there are sceneA and sceneB (current scene) and you call Router.goBack() then there is called the following sequence of methods:

sceneA.onBeforeGoBack();
sceneB.deactivate();
sceneB.trigger('hide');
sceneA.trigger('show');
sceneA.activate();
sceneA.render();
sceneA.focus();

more here: http://smarttv.mautilus.com/SDK/#!/guide/routing

EDIT: sorry I didn't see answer from SoCoxx :)

kingctan commented 8 years ago

OK ,many thaks to @radimbuchtela @SoCoxx ,

then, please @SoCoxx show us: how to pass parameters back to activate() when goback() called? I don't want to change the sdk core source.

Thanks.

mautilus commented 8 years ago

You are probably trying to do something using wrong method. Router.goBack() is working with history. If you want to pass arguments to scene's activate(), then you have to strip last 2 elements from Router.history array and call Router.go('scene',args), like Router.history.splice(-2,2);

Best practice for scene is like:

init: function() {
   this.activated = false;
   this.rendered = false;
},

activate: function(args) {
   if (this.activated) {
      return false;
   }
   var promise = new Promise();
   promise.then(function(state,data) {
       this.activated = true;
   },this);
   // ...
   // some async request which resolves promise
   // ...
   return promise
},

render: function() {
   if (this.rendered) {
      return false;
   }
   // ...
   // some DOM render
   // ...
   this.rendered = true;
}

Scene is activated and rendered only once, which is what you want in most cases.

radimbuchtela commented 8 years ago

I add only NOTE. If you call sequence: Router.go('sceneA', 'parameterA') -> Router.go('sceneB', 'parameterB') -> Router.goBack();

Then after Router.goBack() there is called sceneA.activate('parameterA') automatically with original parameter (here 'parameterA') which was used in previous Router.go('sceneA', 'parameterA').

I am not sure if you are ok to use original parameter 'parameterA' or you want to pass the extra new parameter to sceneA.activate();? I think it is crucial question.

SoCoxx commented 8 years ago

In other words, if you Router.goBack(), the scene on you are going back is called with same parameters in activate(args) as it was called first time with Router.go('scene',args).

Anytime you need to go back with other arguments to the scene, it has nothing to do with history. You should use already mentioned "hack":

Router.history.splice(-2,2);
Router.go('sceneName',newArgs);

Consider if it's really what you need to do ... as I can't imagine situation for this :)

kingctan commented 8 years ago

my scenario is as below:

<div id="scene-test1" style="display:none">
    <div class="page1">

    </div>

    <div class="page2" style="display:none">

    </div>
</div>
<div id="scene-test2" style="display:none">

</div>

since scene-test1 has two page, page1 is a list page, and page2 is a detail page. when page2 to page1, I just change the display,thus scene-test list page can be no refresh every time. but focus on page1 and page2 offten lost when go scene-test2 then goback. so I want pass some parameter to control the focus to corrent item when goback.

any advice to improve my scenario thanks a lot.

SoCoxx commented 8 years ago

I'm not sure if I can clearly understand what you need. Here is some example I've made for you http://sdk-example.mine.sk/ (http://sdk-example.mine.sk/example.zip) - use arrows / enter / backstace to navigate You are probably not using Snippets - an important part of the SDK. Static scenes does not need to use them (or scenes that have no focus that interact with user), but most scenes have to use them. Without Snippets you will end with giant scene object with lots of conditions wich is really bad approach.

Check the example and feel free to ask any question

SoCoxx commented 8 years ago

I've made a second example http://sdk-example-2.mine.sk/ (http://sdk-example-2.mine.sk/example.zip) - showing how snippet scrolling should be done

kingctan commented 8 years ago

OK, @SoCoxx many thanks. I am trying first example.zip and the second example return 403 error. if any problem, I 'll let your know, Thanks.

SoCoxx commented 8 years ago

Yes, wrong permissions, try downloading it now.

Keep in mind, it is a demonstration for Snippets. Raw data content is just appended to DOM without using templates. Although is it functional, it is not clean. But it fulfills the example requirement to be as small as possible and focusing on the main part - Snippets.

kingctan commented 8 years ago

Thanks to @SoCoxx .

I have tried your example, and so in example2, can the scene-info be in the scene-welcome as a snippet-info? thus the scene-welcome need not refresh its data every time when info page go back to grid list page.

hope you can know what i mean, Thanks.

SoCoxx commented 8 years ago

Please, send some example, as it is really hard to imagine, what you are trying to achieve