2017-11-02 13 views
0

ModalDialogServiceに関連する何かが、モーダルにレンダリングされるコンポーネント上のいくつかのものが正しく動作しないようにしています。Nativescript ModalDialogServiceは、コンポーネント上のテキストにバインドできません。

例で実行されているように、タップイベントをコンポーネント上の関数にバインドでき、その中のボタンからモーダルを閉じることができます。

コンポーネントのプロパティにラベルをバインドすると、何も表示されません。他のどこのアプリでも同じコードが表示されます。

コンポーネントを登録するためにentryComponentsを使用する必要があると思われますが、何が起こっているのか把握することはできません。

import { NgModule, ModuleWithProviders } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 

/* Nativescript modules */ 
import { NativeScriptFormsModule } from 'nativescript-angular/forms'; 
import { NativeScriptModule } from 'nativescript-angular/nativescript.module'; 
import { NativeScriptRouterModule } from 'nativescript-angular/router'; 
import { ModalDialogService } from 'nativescript-angular/modal-dialog'; 
import { registerElement } from 'nativescript-angular/element-registry'; 
registerElement('CardView',() => require('nativescript-cardview').CardView); 
/* End nativescript modules */ 

import { StoreModule } from '@ngrx/store'; 
import { EffectsModule } from '@ngrx/effects'; 
import { LoginPageComponent } from './containers/login-page/login-page.component'; 
import { RegisterPageComponent } from './containers/register-page/register-page.component'; 
import { ForgotPasswordPageComponent } from './containers/forgot-password-page/forgot-password-page.component'; 
import { LoginFormComponent } from './components/login-form/login-form.component'; 
import { RegisterFormComponent } from './components/register-form/register-form.component'; 
import { ForgotPasswordFormComponent } from './components/forgot-password-form/forgot-password-form.component'; 
import { TermsComponent } from './components/terms/terms.component'; 

import { AuthService } from './services/auth.service'; 
import { AuthGuard, LazyAuthGuard } from './services/auth-guard.service'; 
import { AuthEffects } from './effects/auth.effects'; 
import { reducers } from './reducers'; 

import { AuthRoutingModule } from './auth-routing.module'; 

export const COMPONENTS = [ 
    LoginPageComponent, 
    RegisterPageComponent, 
    ForgotPasswordPageComponent, 
    LoginFormComponent, 
    RegisterFormComponent, 
    ForgotPasswordFormComponent, 
    TermsComponent, 
]; 

@NgModule({ 
    imports: [ 
    CommonModule, 
    NativeScriptModule, 
    NativeScriptRouterModule, 
    NativeScriptFormsModule, 
    ], 
    declarations: COMPONENTS, 
    exports: COMPONENTS, 
    entryComponents: [TermsComponent], 
    providers: [ 

    ModalDialogService 
    ] 
}) 
export class AuthModule { 
    static forRoot(): ModuleWithProviders { 
    return { 
     ngModule: RootAuthModule, 
     providers: [AuthService, AuthGuard, LazyAuthGuard], 
    }; 
    } 
} 

@NgModule({ 
    imports: [ 
    AuthModule, 
    AuthRoutingModule, 
    StoreModule.forFeature('auth', reducers), 
    EffectsModule.forFeature([AuthEffects]), 
    ], 
}) 
export class RootAuthModule {} 






import { Component } from '@angular/core'; 
import { ModalDialogParams } from 'nativescript-angular/modal-dialog'; 
import { Page } from 'ui/page'; 
@Component({ 
    moduleId: module.id, 
    selector: 'terms-dialog', 
    templateUrl: 'terms.component.html', 
}) 
export class TermsComponent { 
    public test = 'sdfsdfsdfsd'; 
    constructor(private params: ModalDialogParams, private page: Page) { 
    this.page.on('unloaded',() => { 
     // using the unloaded event to close the modal when there is user interaction 
     // e.g. user taps outside the modal page 
     this.params.closeCallback(); 
    }); 
    } 
    public getText(){ 
    return 'some text'; 
    } 
    public close() { 
    debugger; 
    this.params.closeCallback(); 
    } 
} 

<ScrollView sdkExampleTitle sdkToggleNavButton> 
    <StackLayout> 
    <Label horizontalAlignment="left" text="test" class="m-15 h2" textWrap="true"></Label> 
    <Label horizontalAlignment="left" [text]="test" class="m-15 h2" textWrap="true"></Label> 
    <Label [text]="getText()" horizontalAlignment="left" class="m-15 h2" textWrap="true"></Label> 
    <Button row="0" col="1" horizontalAlignment="right" text="&#xf2d4;" class="fa" id="menu-btn" (tap)="close()"></Button> 
    </StackLayout> 
</ScrollView> 







import { 
    Component, 
    OnInit, 
    Input, 
    Output, 
    EventEmitter, 
    ViewContainerRef, 
} from '@angular/core'; 
import { FormGroup, FormControl } from '@angular/forms'; 
import { Register } from '../../models/user'; 
import { Config } from '../../../common/index'; 
import { TermsComponent } from '../terms/terms.component'; 

/* Mobile Specific Stuff */ 
import imagepicker = require('nativescript-imagepicker'); 
import { 
    ModalDialogService, 
    ModalDialogOptions, 
} from 'nativescript-angular/modal-dialog'; 

@Component({ 
    moduleId: module.id, 
    selector: 'bc-register-form', 
    templateUrl: 'register-form.component.html', 
    styleUrls: ['register-form.component.scss'], 
}) 
export class RegisterFormComponent implements OnInit { 
    @Input() 
    set pending(isPending: boolean) { 
    if (isPending) { 
     this.form.disable(); 
    } else { 
     this.form.enable(); 
    } 
    } 

    @Input() errorMessage: string | null; 

    @Output() submitted = new EventEmitter<Register>(); 

    form: FormGroup = new FormGroup({ 
    username: new FormControl(''), 
    password: new FormControl(''), 
    email: new FormControl(''), 
    avatar: new FormControl(''), 
    }); 

    avatarFilePreview: any; 

    constructor(
    public modalService: ModalDialogService, 
    private viewContainer: ViewContainerRef 
) {} 

    ngOnInit() { 
    this.form.get('avatar').valueChanges.subscribe(v => { 
     this.avatarFilePreview = v._files[0]; 
    }); 
    } 

    openDialog() { 
    const options: ModalDialogOptions = { 
     fullscreen: false, 
     viewContainerRef: this.viewContainer, 
     context: {} 
    }; 

    return this.modalService.showModal(TermsComponent, options); 
    } 

    getNativescriptImagePicker() { 
    let context = imagepicker.create({ 
     mode: 'single', 
    }); 
    var self = this; 
    context 
     .authorize() 
     .then(function() { 
     return context.present(); 
     }) 
     .then(function(selection) { 
     self.avatarFilePreview = selection[0]; 
     }) 
     .catch(function(e) { 
     // process error 
     }); 
    } 

    submit() { 
    if (this.form.valid) { 
     this.submitted.emit(this.form.value); 
    } 
    } 
} 


{ 
    "name": "snapnurse-apps", 
    "version": "0.0.0", 
    "repository": "<fill-your-repository-here>", 
    "nativescript": { 
    "id": "com.domain.project", 
    "tns-android": { 
     "version": "3.2.0" 
    }, 
    "tns-ios": { 
     "version": "3.2.0" 
    } 
    }, 
    "dependencies": { 
    "@angular/animations": "~4.1.0", 
    "@angular/common": "~4.1.0", 
    "@angular/compiler": "~4.1.0", 
    "@angular/core": "~4.1.0", 
    "@angular/forms": "~4.1.0", 
    "@angular/http": "~4.1.0", 
    "@angular/platform-browser": "~4.1.0", 
    "@angular/platform-browser-dynamic": "~4.1.0", 
    "@angular/router": "~4.1.0", 
    "@ngrx/db": "^2.0.2", 
    "@ngrx/effects": "^4.1.0", 
    "@ngrx/entity": "^4.1.0", 
    "@ngrx/router-store": "^4.1.0", 
    "@ngrx/store": "^4.1.0", 
    "@ngrx/store-devtools": "^4.0.0", 
    "@ngx-translate/core": "^6.0.1", 
    "@ngx-translate/http-loader": "0.0.3", 
    "nativescript-angular": "^3.1.0", 
    "nativescript-cardview": "^2.0.3", 
    "nativescript-imagepicker": "^4.0.1", 
    "nativescript-ngx-fonticon": "^3.0.0", 
    "nativescript-theme-core": "~1.0.2", 
    "ngrx-store-freeze": "^0.2.0", 
    "reflect-metadata": "~0.1.8", 
    "rxjs": "^5.4.0", 
    "tns-core-modules": "^3.3.0", 
    "zone.js": "~0.8.2" 
    }, 
    "devDependencies": { 
    "@angular/compiler-cli": "~4.1.0", 
    "@ngtools/webpack": "~1.5.5", 
    "@types/jasmine": "^2.5.47", 
    "babel-traverse": "6.25.0", 
    "babel-types": "6.25.0", 
    "babylon": "6.17.4", 
    "copy-webpack-plugin": "~4.0.1", 
    "css-loader": "0.28.2", 
    "del": "^2.2.2", 
    "extract-text-webpack-plugin": "~2.1.0", 
    "gulp": "gulpjs/gulp#4.0", 
    "gulp-debug": "^3.1.0", 
    "gulp-rename": "^1.2.2", 
    "gulp-string-replace": "^0.4.0", 
    "lazy": "1.0.11", 
    "nativescript-css-loader": "~0.26.0", 
    "nativescript-dev-android-snapshot": "^0.*.*", 
    "nativescript-dev-sass": "^1.3.2", 
    "nativescript-dev-typescript": "~0.4.5", 
    "nativescript-dev-webpack": "^0.7.3", 
    "raw-loader": "~0.5.1", 
    "resolve-url-loader": "~2.0.2", 
    "typescript": "~2.3.4", 
    "webpack": "^3.7.1", 
    "webpack-bundle-analyzer": "^2.8.2", 
    "webpack-sources": "~0.2.3" 
    }, 
    "scripts": { 
    "prepPhone": "gulp build.Phone", 
    "prepTablet": "gulp build.Default", 
    "prepCLIPhone": "gulp build.cli.Phone", 
    "prepCLITablet": "gulp build.cli.Default", 
    "ios": "npm run prepCLITablet && tns run ios", 
    "ios.phone": "npm run prepCLIPhone && tns run ios", 
    "android": "npm run prepCLITablet && tns run android", 
    "android.phone": "npm run prepCLIPhone && tns run android", 
    "phone-ios-bundle": "npm run prepPhone && tns prepare ios && npm run start-ios-bundle --uglify", 
    "tablet-ios-bundle": "npm run prepTablet && tns prepare ios && npm run start-ios-bundle --uglify", 
    "build.phone-ios-bundle": "npm run prepPhone && tns prepare ios && npm run build-ios-bundle --uglify", 
    "build.tablet-ios-bundle": "npm run prepTablet && tns prepare ios && npm run build-ios-bundle --uglify", 
    "phone-android-bundle": "npm run prepPhone && tns prepare android && npm run start-android-bundle --uglify", 
    "tablet-android-bundle": "npm run prepTablet && tns prepare android && npm run start-android-bundle --uglify", 
    "build.phone-android-bundle": "npm run prepPhone && tns prepare android && npm run build-android-bundle --uglify", 
    "build.tablet-android-bundle": "npm run prepTablet && tns prepare android && npm run build-android-bundle --uglify", 
    "ns-bundle": "ns-bundle", 
    "livesync": "gulp tns.Livesync", 
    "livesync.phone": "gulp tns.Livesync.Phone", 
    "publish-ios-bundle": "npm run ns-bundle --ios --publish-app", 
    "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install", 
    "start-android-bundle": "npm run ns-bundle --android --run-app", 
    "start-ios-bundle": "npm run ns-bundle --ios --run-app", 
    "build-android-bundle": "npm run ns-bundle --android --build-app", 
    "build-ios-bundle": "npm run ns-bundle --ios --build-app" 
    } 
} 
+0

こんにちは。あなたが共有できるいくつかのコードがありますか? –

+0

@AlexZiskind確かに、それはおそらくドキュメントのようにすべてのものとして役に立たないでしょう。実際に何が起こっているのかをすべてのコードで調べるのではなく、何が起こるのかを考える必要があります。 – Josh

+0

@AlexZiskind認証モジュールと関連コンポーネントを追加しました – Josh

答えて

0

この問題を追跡する時間を費やした後、私はそれを修正する方法を考え出しました。

CustomDialogServiceというクラスを作成します。

import { 
    DetachedLoader, 
    ModalDialogOptions, 
    ModalDialogParams, 
    ModalDialogService, 
    PAGE_FACTORY, 
    PageFactory 
} from "nativescript-angular"; 
import { 
    ComponentFactoryResolver, 
    ComponentRef, 
    Injectable, 
    ReflectiveInjector, 
    Type, 
    ViewContainerRef 
} from "@angular/core"; 
import {View} from "tns-core-modules/ui/core/view"; 
import {Page} from "tns-core-modules/ui/page"; 

interface ShowDialogOptions { 
    containerRef: ViewContainerRef; 
    context: any; 
    doneCallback: any; 
    fullscreen: boolean; 
    pageFactory: PageFactory; 
    parentPage: Page; 
    resolver: ComponentFactoryResolver; 
    type: Type<any>; 
} 

@Injectable() 
export class CustomDialogService implements ModalDialogService { 
    private static showDialog({ 
           containerRef, 
           context, 
           doneCallback, 
           fullscreen, 
           pageFactory, 
           parentPage, 
           resolver, 
           type, 
          }: ShowDialogOptions): void { 
    const page = pageFactory({isModal: true, componentType: type}); 

    let detachedLoaderRef: ComponentRef<DetachedLoader>; 
    const closeCallback = (...args: any[]) => { 
     doneCallback.apply(undefined, args); 
     page.closeModal(); 
     detachedLoaderRef.instance.detectChanges(); 
     detachedLoaderRef.destroy(); 
    }; 

    const modalParams = new ModalDialogParams(context, closeCallback); 

    const providers = ReflectiveInjector.resolve([ 
     {provide: Page, useValue: page}, 
     {provide: ModalDialogParams, useValue: modalParams}, 
     {provide: ViewContainerRef, useValue: containerRef} 
    ]); 

    const childInjector = ReflectiveInjector.fromResolvedProviders(
     providers, containerRef.parentInjector); 
    const detachedFactory = resolver.resolveComponentFactory(DetachedLoader); 
    detachedLoaderRef = containerRef.createComponent(detachedFactory, -1, childInjector); 
    detachedLoaderRef.instance.loadComponent(type).then((compRef) => { 
     compRef.changeDetectorRef.detectChanges(); 
     const componentView = <View>compRef.location.nativeElement; 

     if (componentView.parent) { 
     (<any>componentView.parent).removeChild(componentView); 
     } 

     page.content = componentView; 
     parentPage.showModal(page, context, closeCallback, fullscreen); 
    }); 
    } 

    public showModal(type: Type<any>, 
        {viewContainerRef, moduleRef, context, fullscreen}: ModalDialogOptions): Promise<any> { 
    if (!viewContainerRef) { 
     throw new Error(
     "No viewContainerRef: " + 
     "Make sure you pass viewContainerRef in ModalDialogOptions." 
    ); 
    } 

    const parentPage: Page = viewContainerRef.injector.get(Page); 
    const pageFactory: PageFactory = viewContainerRef.injector.get(PAGE_FACTORY); 

    // resolve from particular module (moduleRef) 
    // or from same module as parentPage (viewContainerRef) 
    const componentContainer = moduleRef || viewContainerRef; 
    const resolver = componentContainer.injector.get(ComponentFactoryResolver); 

    return new Promise(resolve => { 
     setTimeout(() => CustomDialogService.showDialog({ 
     containerRef: viewContainerRef, 
     context, 
     doneCallback: resolve, 
     fullscreen: !!fullscreen, 
     pageFactory, 
     parentPage, 
     resolver, 
     type, 
     }), 10); 
    }); 
    } 
} 

次に、あなたのNgModuleで、あなたのプロバイダの配列にこのプロバイダを追加します。

{ provide: ModalDialogService, useClass: CustomDialogService }

をこれが私たちの新しいCustomDialogServiceいると、デフォルトのModalDialogServiceを上書きしますバグを修正!

関連する問題