Closed BenevidesLecontes closed 8 years ago
@vakrilov I had been chatting with @BenevidesLecontes but I am also unsure of how best to modify Page
level properties in an angular component? The OpaqueToken
setup is just to allow it to work on web and {N}. so don't be confused by all that above ^. Bottom line: how best to modify Page
props within angular components.
I'm not sure if I understand the issue correctly so - correct me if, I'm wrong.
I'm assuming the problem is the code sharing between web and mobile - no Page in web projects.
In this case I would suggest extracting the mobile-specific code in a directive that is only used in the {N} part. You can inject Page
directly there as the code will be executed only in {N} context. You won't need the token and you will have typing support for the Page
type.
Note: You can inject Page
in any component/directive and it will be the page the component/directive will be displayed on.
@vakrilov yes you're right, i'm using <page-router-outlet></page-router-outlet>
to load my components, does the same thought apply to that case?
After read your suggestion, I tried to use router-outlet
to use Page inside my component, it keep throwing error, Cannot find primary outlet to load 'LoginComponent'
PS: I have ROUTER_DIRECTIVES in my components metadata.
For the actual markup - you will probably have different files for web/mobile as the markup will be different. That said - the error you are getting is not expected - can you share some repo code?
@vakrilov I think the actual issue has gotten clouded by some other things mentioned here. The real question is why this doesn't work:
import {Page} from 'ui/page';
...
constructor(private page:Page) {
this.page.actionBarHidden = true;
this.page.backgroundSpanUnderStatusBar=true;
this.page.backgroundImage = this.page.ios ? "res://bg_login.jpg" : "res://bg_login";
}
changing props on injected Page
appear to have no effect?
Indeed I missed that - will investigate. Does this happen:
On both. iOS at least, haven't checked Android.
I was unable to reproduce the behavior. Here is how I tested - the background is changed here as expected.
Can you share some code?
Thank you @vakrilov for taking the time to look. Let's close this and I'll look at this again with him.
Just to conclude, turns out his issue was related to fact that when using an OpaqueToken
to build a web/{N} shared codebase, one must provide the PAGE
OpaqueToken
in the correct way, for instance this works:
// somewhere in web codebase
import {OpaqueToken} from '@angular/core';
export const PAGE: any = new OpaqueToken('page');
...
// then only in the {N} app
nativeScriptBootstrap(AppComponent, [
provide(PAGE, {
useFactory: () => {
const frame = topmost();
if (frame) {
return frame.currentPage;
} else {
return null;
}
}
})
]);
... then in a component which is used on the web (as well as in {N} app), one can do this:
@Component({
selector: 'any-cmp',
templateUrl: 'any.component.html'
})
export class AnyComponent {
constructor(@Inject(PAGE) private page:any) {
if (Config.IS_MOBILE_NATIVE()) {
this.page.actionBarHidden = true;
this.page.backgroundSpanUnderStatusBar = true;
this.page.backgroundImage = 'res://bg_login';
}
}
Works wonderfully and ensures that it doesn't break the web 👍
That save me days!
@NathanWalker This method looks good but I haven't been able to get this to work. Is provide a class I should import or create? Or has the standard changed?
Hi! i'm using angular2-seed-advanced, web + mobile with angular+nativescript, i'm trying to set my background sitting under statusbar using opaqueTokens, but somehow it don't work. My code: Token.ts
App.ts
myComponent.ts