in theory, you can put the Activated trigger in a page that is inside of a Navigator just fine. In some rare cases, you might need to add a Bypass="Never" property on it.
Have you tried the code you posted? Did it work or not?
And what are you willing to do in that second-level Callback? Maybe there’s a better way to achieve the goal.
yes I have tried the code and the “activated” is called when the class is instanced.
In my app I have 2 tabs:
Home --> with it’s own navigator/router so u can navigate to a person profile (for example)
Search nearby --> also with own navigator/router that search places nearby
the first time you click on the search tab it should search for the places near you.
Now i’m calling the “first search” function on the “tab click” but i get an error (actually i just get the error on the monitor but it works) so that’s why I ask if there is a way to trigger something when showing that page.
If you want to do something only once, the you have to store somewhere the fact that you have done this thing when you have done it. This might be a boolean variable in a stand-alone JavaScript module, for example.
Then, when you run the function X every time you land on the page, you can check the value of that boolean, launch search and update the boolean as necessary.
Now, if you’re saying there is an error, then you should report that error in a separate thread along with a self-contained reproduction, so we could check and hopefully solve it for you.
my problem is NOT that i don’t know how to do something once I just ask if there is a way of calling a JS function INSIDE the CustomPage when this page is shown.
I’ll post a more complex example as i don’t think the error i get it’s a bug
In this example there is a Pager (ux:Name=“pager”) that contains 2 pages:
ux:Name=“page1”: just text
ux:Name=“page2”: It contains a router/navigator with 2 pages:
CustomPage
CustomPage2
On the bottom there is a panel that allows you to navigate the 2 main pages.
I want that as soon as CustomPage is shown it navigates to CustomPage2. In this example I run this code once you click on the bottom bar so you get an error as when you call “runCodeInside() function on customPage.js” router is not defined (it makes sense).
So my question is:
following this example is there a way of being able to navigate from CustomPage to CustomPage2 (make runCodeInside() working) as soon as CustomPage is shown?
the direct answer to your question is there a way to...? is YES. However, there are a couple things.
You’re using router wrong. In most cases, you only need one, put at the root of your app, and definitely NOT with IsMasterRouter="false".
You’re using a single JS file both as a viewmodel: <JavaScript File="customPage.js"/> and as a stand-alone module: var CP = require("customPage.js");. You MAY NOT do that; it’s either one or the other.
Even though I spent a lot of time trying to understand what it is you’re trying to achieve, I still don’t see how this might be useful. Mostly because it doesn’t make sense to “immediately redirect to another page” - then why have that first page there in the first place?!
I would suggest you to rethink your approach, formulate a good question and maybe start with a real-world description of what it is you want to make. Maybe then we could get somewhere, because this direction clearly won’t lead us anywhere.
Finally, here’s some code that I could jumble together as a proof-of-concept:
<App>
<Router ux:Name="router" />
<JavaScript>
module.exports = {
gotoPageOne: function() {
router.goto("page1", {});
},
gotoPageTwo: function() {
// we have to pass full path to first subpage, because
// we might have navigated to the second subpage already
router.goto("page2", {}, "page2c1", {});
}
};
</JavaScript>
<DockPanel>
<PageControl>
<Page ux:Name="page1">
<Text Value="page1"/>
</Page>
<Page ux:Name="page2">
<Navigator ux:Name="subNav" DefaultPath="page2c1">
<CustomPage ux:Template="page2c1" router="router" subPages="subNav" />
<CustomPage2 ux:Template="page2c2" router="router"/>
</Navigator>
</Page>
</PageControl>
<Grid Dock="Bottom" ColumnCount="2" Height="50">
<Panel HitTestMode="LocalBoundsAndChildren" Background="#ff00aa">
<Text Value="Go to Page1" TextColor="#fff" Alignment="VerticalCenter" TextAlignment="Center"/>
<Clicked>
<Callback Handler="{gotoPageOne}" />
</Clicked>
</Panel>
<Panel HitTestMode="LocalBoundsAndChildren" Background="#aa00ff">
<Text Value="Go to Page2" TextColor="#fff" Alignment="VerticalCenter" TextAlignment="Center"/>
<Clicked>
<Callback Handler="{gotoPageTwo}" />
</Clicked>
</Panel>
</Grid>
</DockPanel>
<Page ux:Class="CustomPage">
<Router ux:Dependency="router" />
<Navigator ux:Dependency="subPages" />
<JavaScript>
module.exports = {
gotoCustomPageTwo: function() {
// whenever we hit the Activated, proceed to second subpage
router.pushRelative(subPages, "page2c2", {});
}
}
</JavaScript>
<Activated>
<Callback Handler="{gotoCustomPageTwo}" />
</Activated>
<Text Value="Custom Page One"/>
</Page>
<Page ux:Class="CustomPage2">
<Router ux:Dependency="router" />
<JavaScript>
module.exports = {
goBack: function() {
// and this makes no sense, because we will immediately land
// back on the second subpage because of that Activated
router.goBack();
}
}
</JavaScript>
<StackPanel>
<Text Value="CustomPage2"/>
<Button Text="Go Back!" Margin="0,20,0,0">
<Clicked Handler="{goBack}"/>
</Button>
</StackPanel>
</Page>
</App>
I dont’ want to navigate from one to another it was just one example as said in the first post i just want to be able to run some code when the page is shown. “hello world” would be fine too but i used the “navigation” example as you can’t call it from outside the customPage.js
I use IsMasterRouter=“false” as in my original app i have more than one router and there is more stuff but that’s not relevant here
So pls forget about all the stuff before and i’ll try to be very clear:
let’s say I have this code:
<App>
<Router ux:Name="router"/>
<JavaScript>
function p1Active(){
console.log("p1 on the screen!");
}
function p2Active(){
console.log("p2 on the screen!");
}
module.exports = {
p1Active: p1Active,
p2Active: p2Active
}
</JavaScript>
<DockPanel>
<PageControl ux:Name="pager">
<Page ux:Name="page1">
<Text Value="page1"/>
</Page>
<Page ux:Name="page2">
<Text Value="page2"/>
</Page>
</PageControl>
<Grid Dock="Bottom" ColumnCount="2" Height="50">
<Panel HitTestMode="LocalBoundsAndChildren" Background="#ff00aa">
<Text Value="Go to Page1" TextColor="#fff" Alignment="VerticalCenter" TextAlignment="Center"/>
<Clicked>
<Set pager.Active="page1"/>
</Clicked>
</Panel>
<Panel HitTestMode="LocalBoundsAndChildren" Background="#aa00ff">
<Text Value="Go to Page2" TextColor="#fff" Alignment="VerticalCenter" TextAlignment="Center"/>
<Clicked>
<Set pager.Active="page2"/>
</Clicked>
</Panel>
</Grid>
</DockPanel>
</App>
if i ask you:
Is there a way to execute the p1Active and p2Active functions each time page1 and page2 are shown on the screen?
you would say: “YES just add this code inside the Page tags”
I want pageOnActivated function inside CustomPage to run each time CustomPage is shown on the screen (exactly the same way that the p1Active and p2Active functions are run when page1 and page 2 are shown on the screen)
If i use the Activated tag it just run on app start and i would like it to be executed each time it appears on the screen (when i navigate to page2 and when i click on “go Back” from CustomPage2)
I think that the main problem with this structure is the following. Inside your PageControl, the pages are instances (not templates as in a Navigator), so they have to be created at start. That explains why the pageOnActivated() is called during app startup - its parent page gets created, and on that page the Navigator has to spawn the child mentioned in DefaultPath. So it gets Activated.
Now, when you later navigate to page2 on the first level, the first subpage in Navigator is already active, so it doesn’t get Activated again.
A workaround might be to navigate to full path, e.g. router.goto("page2", {}, "subpage1", {}); but that remains to be tested.
Also, I believe some changes to Activated triggers are expected to ship in the coming weeks, but there’s no more specific details available at this point. We’ll keep you posted.