用角度2改变检测问题

时间:2016-09-19 10:47:25

标签: angular typescript

详细

我试图在形式上实现ng2-select有问题它没有检测到它自身的角度变化。我尝试用zone.run()运行我所需的asycn任务nnow问题是当我触发重置或提交表单时显示ng2-select中的数据。否则它在inut feild中显示未定义的值,并且在ng2-select

中没有显示任何响应

enter image description here

触发后

enter image description here

的HTML

    <div class="col-md-12">
        <!-- Reg-Form -->
        <form id="sky-form4" class="sky-form" (ngSubmit)="Submit(userEdit)" #userEdit="ngForm">
            <header>Edit User Account</header>

            <fieldset>
                <section>
                    <label class="input">
                        <i class="icon-append fa fa-user"></i>
                        <input type="text" name="username" placeholder="First Name" required [value]="fname">
                        <b class="tooltip tooltip-bottom-right">Enter First Name</b>
                    </label>
                </section>

                <section>
                    <label class="input">
                        <i class="icon-append fa fa-user"></i>
                        <input type="text" name="username" placeholder="Last Name" [value]="lname">
                        <b class="tooltip tooltip-bottom-right">Enter Last Name</b>
                    </label>
                </section>

                <section>
                    <label class="input">
                        <i class="icon-append fa fa-envelope"></i>
                        <input type="email" name="email" placeholder="Email address" [value]="email">
                        <b class="tooltip tooltip-bottom-right">Enter Email Address</b>
                    </label>
                </section>

                <section>
                    <label>
                        Roles
                    </label>
                    <div *ngIf="roles.length > 0">
                        <ng-select [initData]="initRoleData"
                                   [multiple]="true"
                                   [items]="roles"
                                   (data)="refreshValue($event)"
                                   (selected)="selected($event)"
                                   (removed)="removed($event)"
                                   placeholder="No roles assign">
                        </ng-select>
                    </div>
                </section>
                
                <section>
                    <label>
                        Groups
                    </label>
                    <div *ngIf="groups.length > 0">
                        <ng-select [initData]="initGroupData"
                                   [multiple]="true"
                                   [items]="groups"
                                   (data)="refreshValue($event)"
                                   (selected)="selected($event)"
                                   (removed)="removed($event)"
                                   placeholder="No groups assign">
                        </ng-select>
                    </div>
                </section>
            </fieldset>
            <footer>
                <button type="reset" class="btn-u">Cancel</button>
                <button type="submit" class="btn-u" [disabled]="!userEdit.form.valid">Save</button>
            </footer>
        </form>
        <!-- End Reg-Form -->
    </div>

</div><!--/end row-->

TS

@Component({
    selector: 'users-edit',
    templateUrl: '../../app/components/user/user-edit.html',
    directives: [SELECT_DIRECTIVES],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserEditComponent implements OnInit {
    private isAdmin: Boolean = false;
    private _data: Observable<any[]>;
    private fname: string;
    private id: number;
    private lname: string;
    private email: string;
    private _roles: Observable<any[]>;
    public roles: any = [];
    public groups: any = [];
    private initRoleData: Array<any>[] = [];
    private initGroupData: Array<any>[] = [];


    public selected(value: any): void {
        console.log('Selected value is: ', value);
    }

    public removed(value: any): void {
        console.log('Removed value is: ', value);
    }

    public refreshValue(value: any): void {
        this.initRoleData = value;
    }


    constructor(private router: Router,
        private userService: UserService,
        private route: ActivatedRoute,
        private authService: AuthService,
        private _ngZone: NgZone,
        private ref: ChangeDetectorRef) {
        this._ngZone.run(() => {
            this.isCurrentUserAdmin();
            this.route.params.subscribe(params => {
                this.id = +params['id'];
            });
        });
    }

    private isCurrentUserAdmin() {
        this.userService.isCurrentUserAdmin(this.authService.getUserName())
            .subscribe(data => {
                this.isAdmin = Boolean(data);
            },
            error => {
                console.log("error while retriving admin");
                console.log(error);
                this.userService.handleError(error);
            });
    }

    ngOnInit() {
        this._ngZone.run(() => {
            this.userService.getUser(this.id)
                .subscribe(data => {
                    this.fname = data.FirstName;
                    this.lname = data.LastName;
                    this.email = data.Email;
                });
            this.getUserGroupByIdFunc();

            this.getUserRoleByIdFunc();

            this.userService.getAllRoles()
                .subscribe(data => {
                    data.forEach(role => {
                        this.roles.push(role.Name);
                        this.ref.detectChanges();
                    });
                });

            this.userService.getAllGroups()
                .subscribe(data => {
                    data.forEach(group => {
                        this.groups.push(group.Name);
                        this.ref.detectChanges();
                    });
                });
        });
        this.ref.markForCheck();
    }

    getUserRoleByIdFunc() {
        this._ngZone.run(() => {
            this.userService.getUserRolesById(this.id)
                .subscribe(data => {
                    data.forEach(role => {
                        this.initRoleData.push(role.Name);
                        this.ref.detectChanges();
                    });
                });
        });
    }


    getUserGroupByIdFunc() {
        this._ngZone.run(() => {
            this.userService.getUserGroupsById(this.id)
                .subscribe(data => {
                    data.forEach(group => {
                        this.initGroupData.push(group.Name);
                        this.ref.detectChanges();
                    });
                });
        });
    }

    Submit(form: any) {
        alert(form);

    }

}

1 个答案:

答案 0 :(得分:0)

在Angular 2/4/5中使用changeDetection OnPush时。请使用以下内容:

  1. array = [...array,...element];代替array = array.push(element); 这将通过将项目推入数组来触发更改检测。
  2. this.ref.markForCheck();在每个订阅中。
  3. 这将使changeDetection适用于您的情况。

    链接供参考:https://alligator.io/angular/change-detection-strategy/

    以下是您的组件的更新.ts。

    @Component({
        selector: 'users-edit',
        templateUrl: '../../app/components/user/user-edit.html',
        directives: [SELECT_DIRECTIVES],
        changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class UserEditComponent implements OnInit {
        private isAdmin: Boolean = false;
        private _data: Observable<any[]>;
        private fname: string;
        private id: number;
        private lname: string;
        private email: string;
        private _roles: Observable<any[]>;
        public roles: any = [];
        public groups: any = [];
        private initRoleData: Array<any>[] = [];
        private initGroupData: Array<any>[] = [];
    
    
        public selected(value: any): void {
            console.log('Selected value is: ', value);
        }
    
        public removed(value: any): void {
            console.log('Removed value is: ', value);
        }
    
        public refreshValue(value: any): void {
            this.initRoleData = value;
        }
    
    
        constructor(private router: Router,
            private userService: UserService,
            private route: ActivatedRoute,
            private authService: AuthService,
            private _ngZone: NgZone,
            private ref: ChangeDetectorRef) {
            this._ngZone.run(() => {
                this.isCurrentUserAdmin();
                this.route.params.subscribe(params => {
                    this.id = +params['id'];
                    this.ref.markForCheck();
                });
            });
        }
    
        private isCurrentUserAdmin() {
            this.userService.isCurrentUserAdmin(this.authService.getUserName())
                .subscribe(data => {
                    this.isAdmin = Boolean(data);
                    this.ref.markForCheck();
                },
                error => {
                    console.log("error while retriving admin");
                    console.log(error);
                    this.userService.handleError(error);
                    this.ref.markForCheck();
                });
        }
    
        ngOnInit() {
            this._ngZone.run(() => {
                this.userService.getUser(this.id)
                    .subscribe(data => {
                        this.fname = data.FirstName;
                        this.lname = data.LastName;
                        this.email = data.Email;
                        this.ref.markForCheck();
                    });
                this.getUserGroupByIdFunc();
    
                this.getUserRoleByIdFunc();
    
                this.userService.getAllRoles()
                    .subscribe(data => {
                        data.forEach(role => {
                            this.roles = [...this.roles,...role.Name];
                        });
                        this.ref.markForCheck();
                    });
    
                this.userService.getAllGroups()
                    .subscribe(data => {
                        data.forEach(group => {
                            this.groups = [...this.groups,...group.Name];
                        });
                        this.ref.markForCheck();
                    });
                this.ref.markForCheck();
            });
    
        }
    
        getUserRoleByIdFunc() {
            this._ngZone.run(() => {
                this.userService.getUserRolesById(this.id)
                    .subscribe(data => {
                        data.forEach(role => {
                            this.initRoleData = [...this.initRoleData,...role.Name];
                        });
                        this.ref.markForCheck();
                    });
            });
        }
    
    
        getUserGroupByIdFunc() {
            this._ngZone.run(() => {
                this.userService.getUserGroupsById(this.id)
                    .subscribe(data => {
                        data.forEach(group => {
                            this.initGroupData = [...this.initGroupData,...group.Name];
                        });
                        this.ref.markForCheck();
                    });
            });
        }
    
        Submit(form: any) {
            alert(form);
    
        }
    
    }