我正在引导程序模版中构建一个注册表单。 提交(按下按钮)后,模式不会关闭。 我不能使用data-dismiss属性,因为在将数据提交到服务器端进行注册之前,该模式将被关闭。 试图使用ngbactivemodal解决它,但似乎我在执行bootstrap-angular期间所做的事情是不正确的。 附件为:
寄存器组件。ts-
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { matchOtherValidator } from '../match-other-validator';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
import { map,take,switchMap} from 'rxjs/operators';
import { RegisterService } from '../register.service';
import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'
const tzAsyncValidator = (http: HttpClient) => (c: FormControl) => {
console.log(c.parent);
if (!c || String(c.value).length === 0) {
console.log("!c|| String (c.value).length ===0")
return of(null);
}
return c.valueChanges.pipe(
take(1),
switchMap(_ =>
http.get('http://localhost:4000/userIds/' + String(c.value))
.pipe(
map((ids: any[]) => {
console.log(ids);
if (ids.length === 1) {
return { exists: true }
}
if (ids.length === 0) {
return null;
}
}))
))
}
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
public newUser;
public verification=false;
public newUser2;
public finalUser;
constructor(private http: HttpClient, public RS:RegisterService, private activeModal: NgbActiveModal) { }
ngOnInit() {
this.newUser = new FormGroup({
Tz: new FormControl('', [Validators.required, Validators.minLength(9), Validators.maxLength(9)], [tzAsyncValidator(this.http)]),
Email: new FormControl('', [Validators.required, Validators.email]),
PW: new FormControl('', [Validators.required, Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$')]),
PWVerification: new FormControl('', [Validators.required, Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$'), matchOtherValidator('PW')])
})
}
onSubmit(){
this.verification=true;
this.newUser2= new FormGroup({
City: new FormControl ('',Validators.required),
Street: new FormControl('',Validators.required),
FirstName: new FormControl('',Validators.required),
LastName: new FormControl('',Validators.required)
})
}
onSubmit2(){
this.finalUser=({...this.newUser.value,...this.newUser2.value});
this.RS.RegisterUser(this.finalUser)
.subscribe(()=>{
console.log(this.activeModal);
this.activeModal.close();
})
}
}
注册组件html-
<div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog"
aria-labelledby="staticBackdropLabel" aria-hidden="true" data-toggle="modal" >
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Sign Up!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form [formGroup]="newUser" (ngSubmit)='onSubmit()' *ngIf="verification!=true">
<label>ID</label>
<br>
<input type="text" placeholder="Please Enter Your ID" formControlName="Tz">
<br>
<label>Email</label>
<br>
<input type="email" placeholder="Please Enter Your Email" formControlName="Email">
<br>
<label>Password</label>
<br>
<input type="text" name="password" placeholder="Please Choose A Password" formControlName="PW" size="25">
<br>
<label>Resubmit Your Password</label>
<br>
<input type="text" name="confirmPassword" placeholder="Please Resubmit Your Password"
formControlName="PWVerification" validateEqual="password" size="30">
<br>
<input type="submit" class="btn btn-success" [disabled]="!newUser.valid">
<br>
<span *ngIf="newUser.get('Email').invalid &&!newUser.get('Email').pristine">Your email does not look
right</span>
<br>
<span *ngIf="newUser.get('Tz').errors?.maxlength ||newUser.get('Tz').errors?.minlength ">Your ID must contain
9 digits</span>
<br>
<span *ngIf="newUser.get('PW').invalid&&!newUser.get('PW').pristine">Password must include at least one letter
and one digit</span>
<br>
<span *ngIf="newUser.get('PWVerification').errors?.matchOther">Your submitted passwords don't match</span>
<br>
<span *ngIf="newUser.get('Tz').errors?.exists">This ID already exists</span>
</form>
<form [formGroup]="newUser2" *ngIf="verification!=false">
<label>City</label>
<br>
<input list="City" name="City" formControlName="City" placeholder="Choose City">
<datalist id="City">
<option value="Jerusalem">
<option value="Tel Aviv">
<option value="Haifa">
<option value="Rishon LeZion">
<option value="Petach Tikva">
<option value="Ashdod">
<option value="Netanya">
<option value="Be'er Sheva">
<option value="Holon">
<option value="Bnei Brak">
</datalist>
<br>
<label>Street</label>
<br>
<input type="text" placeholder="Please Input Street for Delivery" formControlName="Street">
<br>
<label>First Name</label>
<br>
<input type="text" placeholder="First Name here" formControlName="FirstName">
<br>
<label>Last Name</label>
<br>
<input type="text" placeholder="Last Name here" formControlName="LastName">
<br>
<input type="submit" class="btn btn-success" [disabled]="!newUser2.valid" (click)="onSubmit2()">
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
app.module.ts-
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule} from '@angular/common/http';
import { RegisterComponent } from './register/register.component';
import {NgbModule, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
@NgModule({
declarations: [
AppComponent,
RegisterComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
HttpClientModule,
NgbModule
],
providers: [NgbActiveModal],
bootstrap: [AppComponent]
})
export class AppModule { }
index.html-
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>YoavOnlineShop</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
angular.json-
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"YoavOnlineShop": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/YoavOnlineShop",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "YoavOnlineShop:build"
},
"configurations": {
"production": {
"browserTarget": "YoavOnlineShop:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "YoavOnlineShop:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "YoavOnlineShop:serve"
},
"configurations": {
"production": {
"devServerTarget": "YoavOnlineShop:serve:production"
}
}
}
}
}},
"defaultProject": "YoavOnlineShop"
}
package.json-
{
"name": "yoav-online-shop",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~8.2.9",
"@angular/common": "~8.2.9",
"@angular/compiler": "~8.2.9",
"@angular/core": "~8.2.9",
"@angular/forms": "~8.2.9",
"@angular/platform-browser": "~8.2.9",
"@angular/platform-browser-dynamic": "~8.2.9",
"@angular/router": "~8.2.9",
"@ng-bootstrap/ng-bootstrap": "^5.1.4",
"rxjs": "~6.4.0",
"tslib": "^1.10.0",
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.803.8",
"@angular/cli": "~8.3.8",
"@angular/compiler-cli": "~8.2.9",
"@angular/language-service": "~8.2.9",
"@types/node": "~8.9.4",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "^5.0.0",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.5.3"
}
}
答案 0 :(得分:0)
将ng-bootstrap提供到 package.json:
"dependencies": {
... // dependencies over here
"@ng-bootstrap/ng-bootstrap": "xxx"
}
然后在 angular.json中:
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
我没有将任何js导入我的 index.html
最后,在我的组件中,我改用NgbModalRef。我正在发布整个组件,因此对样板代码感到抱歉。
import {Component, OnInit, ViewEncapsulation} from '@angular/core';
import {ParamsService} from '../../services/params.service';
import {NgbModal, NgbModalRef} from '@ng-bootstrap/ng-bootstrap';
import {NgxSpinnerComponent, NgxSpinnerService} from 'ngx-spinner';
import {FormBuilder, FormGroup, Validators, FormControl} from '@angular/forms';
import {UserService} from '../../services/user.service';
import {StudyDirection} from '../../model/direction.model';
import {forEach} from '@angular/router/src/utils/collection';
@Component({
selector: 'app-directions',
templateUrl: './directions.component.html',
styleUrls: ['./directions.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class DirectionsComponent implements OnInit {
public directions: StudyDirection[];
public direction: StudyDirection;
public modalRef: NgbModalRef;
public form: FormGroup;
public tempDirection: StudyDirection;
constructor(private paramService: ParamsService,
private modalService: NgbModal,
private spinner: NgxSpinnerService,
private fb: FormBuilder,
private userService: UserService) {
}
ngOnInit() {
this.getDirections();
this.form = this.fb.group({
code: [null, Validators.required],
name: [null, Validators.required],
description: null,
parentDirectionid: null,
});
}
getDirections() {
this.paramService.getDirectionsList().subscribe(directions => {
this.directions = directions;
});
}
openAddModal(content) {
this.direction = new StudyDirection();
this.modalRef = this.modalService.open(content, {container: '.app'});
this.modalRef.result.then((result) => {
this.form.reset();
}, (reason) => {
this.form.reset();
});
}
deleteDirection(direction) {
this.spinner.show();
this.paramService.removeDirection(direction).subscribe(response => {
this.getDirections();
this.spinner.hide();
}, error => {
this.spinner.hide();
});
}
addDirection(directionid) {
this.paramService.addDirection(directionid).subscribe(response => {
this.getDirections();
this.modalRef.close();
}, error => {
console.log(error);
});
console.log(directionid);
}
closeModal() {
this.modalRef.close();
}
}
.app是我主题之外的一个类。所以我的模态开始于:
this.modalRef = this.modalService.open(content, {container: '.app'});
然后将其关闭:
this.modalRef.close();