首页 文章

NativeScript:显示ActivityIndicator时禁用所有控件

提问于
浏览
1

假设有一个登录页面,其中包含用户名\密码TextFields和登录按钮 . 按下按钮时,会向服务器设置一个请求,并显示ActivityIndicator . 目前,我将StackLayout置于所有其他控件之上,不让用户在处理请求时单击它们 . 但在某些情况下,TextField保持专注,用户可以在那里输入 .

我已经使用一个组件来包装所有TextField以显示验证错误:

@Component({
  selector: "field",
  template: "<grid-layout><ng-content></ng-content>...</grid-layout>"
})
export class FieldComponent {
  @ContentChild(NgModel) private input: NgModel;
  ...
}

我的问题是我可以在具有 NgModelng-contentng-content 中的TextField上将isEnabled属性设置为false,还是以其他方式设置?如果不可能在这种情况下在应用程序繁忙时禁用输入的最佳做法是什么?

3 回答

  • 2

    有几种方法可以做到这一点;

    • 您可以使用 ngIfisEnabled 上的绑定根据数据绑定值禁用它 .

    • 您可以创建一个您调用的简单例程(我的首选方法) .

    require("nativescript-dom"); function screenEnabled(isEnabled) { runAgainstTagNames('TextEdit', function(e) { e.isEnabled = isEnabled; }); runAgainstTagNames('Button', function(e) { e.isEnabled = isEnabled; }); }

    nativescript-dom 插件有runAgainst *或getElementBy *包装器与本机层通信,就像你正在与html dom交谈一样 .

    完全披露,我是 nativescript-dom 的作者,它是我在几乎每个app / demo中使用的插件之一 .

  • 0

    这是我对NativeScript Angular的解决方案:

    • setControlInteractionState()是递归的 .

    • 隐藏TextField游标(使用本机android API) .

    XML:

    <GridLayout #mainGrid rows="*" columns="*">  
      <!-- Main page content here... -->
      <GridLayout *ngIf="isBusy" rows="*" columns="*">
         <GridLayout rows="*" columns="*" style="background-color: black; opacity: 0.35">
         </GridLayout>
         <ActivityIndicator width="60" height="60" busy="true">
         </ActivityIndicator>
      </GridLayout>
    </GridLayout>
    

    要么

    <GridLayout #mainGrid rows="*" columns="*">  
      <!-- Main page content here... -->      
    </GridLayout>
    <GridLayout *ngIf="isBusy" rows="*" columns="*">
       <GridLayout rows="*" columns="*" style="background-color: black; opacity: 0.35">
       </GridLayout>
       <ActivityIndicator width="60" height="60" busy="true">
       </ActivityIndicator>
    </GridLayout>
    

    TypeScript:

    import { Component, ViewChild, ElementRef } from "@angular/core";
    import { View } from "ui/core/view";
    import { LayoutBase } from "ui/layouts/layout-base";
    import { isAndroid, isIOS } from "platform";
    
    @Component({
        templateUrl: "./SignIn.html"
    })
    export class SignInComponent {
    
        @ViewChild("mainGrid")
        MainGrid: ElementRef;
    
        isBusy: boolean = false;
    
        submit() : void {
            try {
                this.isBusy = true;
                setControlInteractionState(<View>this.MainGrid.nativeElement, false);
                //sign-in here...
            }
            finally {
                this.isBusy = false;
                setControlInteractionState(<View>this.MainGrid.nativeElement, true);
            }
        }
    
        setControlInteractionState(view: View, isEnabled: boolean) : void {
            view.isUserInteractionEnabled = isEnabled;
            if (isAndroid) {
                if (view.android instanceof android.widget.EditText) {
                    let control = <android.widget.EditText>view.android;
                    control.setCursorVisible(isEnabled);
                }
            }
            if (view instanceof LayoutBase) {
                let layoutBase = <LayoutBase>view;
                for (let i = 0, length = layoutBase.getChildrenCount(); i < length; i++) {
                    let child = layoutBase.getChildAt(i);
                    setControlInteractionState(child, isEnabled);
                }
            }
        }
    
    }
    

    NS 2.5.0

  • 3

    扩展@KTCO的答案,使叠加层的大小与主网格完全相同:

    import { Size, View } from "tns-core-modules/ui/core/view";
    import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout/grid-layout";
    ...
    ...
    dialogSize: Size;
    mainGrid: GridLayout;
    ...
    submit() {
      this.mainGrid = <GridLayout>this.MainGrid.nativeElement;
      this.dialogSize = this.mainGrid.getActualSize();
      .....
      .....
    
    <GridLayout *ngIf="isBusy" rows="auto" columns="auto">
      <GridLayout rows="*" columns="*" [width]="dialogSize.width" [height]="dialogSize.height" style="background-color: black; opacity: 0.35">
      </GridLayout>
      <ActivityIndicator width="50" height="50" busy="true">
      </ActivityIndicator>
    </GridLayout>
    

相关问题