首页 文章

在Angular 2中创建用户时更新用户列表

提问于
浏览
2

我正在编写一个示例应用程序,我有一个用户列表组件:

@Component({
  selector: 'user-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css'],
})
export class ListComponent implements OnInit {
  users: Array = [];
  private usersService: UsersService;

  constructor(private service: UsersService) {
    this.usersService = service;
  }

  loadUsers() {
    this.usersService.getUsers().subscribe(users => this.users = users);
  }

  ngOnInit() {
    this.loadUsers();
    this.usersService.userEvent.subscribe(user => this.loadUsers());
  }
}

服务是:

@Injectable()
export class UsersService {
  userEvent: EventEmitter = new EventEmitter();


  constructor(private http: Http) {
  }
  getUsers(): Observable {
    return this.http.get('/rest/users')
      .map(res => res.json());
  }

  create(user: User) {
    this.http.post("/rest/users", user).subscribe(resp => this.userEvent.emit(user));
  }
}

export class User {
  constructor(public username: string,
    public email: string, public password: string
  ) { }
}

并且有一个用于创建用户的兄弟组件:

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
  private usersService: UsersService;
  constructor(private service: UsersService, private router: Router) {
    this.usersService = service;
  }

  ngOnInit() {
  }

  onSubmit(formValue: any) {
    let user = new User(formValue.username, formValue.email, formValue.password);
    this.usersService.create(user);
    this.router.navigate(['users']);
  }

}

这目前正在做我想做的事情,但我想知道在兄弟组件在服务器上创建新用户的情况下是否有更优雅的方式来更新用户列表 . 如果我订阅用户列表,则必须使用事件 Launcher 发出信号似乎很奇怪,尽管我也不知道如何通知http.get有关在服务器上创建新用户的信息 .

2 回答

  • 1

    这是我的库RxCache旨在管理的确切类型 . 它会为您处理所有可观察的订阅,这样您就不必管理任何订阅或担心订阅泄漏 .

    https://github.com/adriandavidbrand/ngx-rxcache

    在组件中,您可以公开用户的可观察量和加载标志 .

    @Component({
      selector: 'user-list',
      templateUrl: './list.component.html',
      styleUrls: ['./list.component.css'],
    })
    export class ListComponent implements OnInit {
      users$ = this.service.users$;
      loading$ = this.service.loading$;
    
      constructor(private service: UsersService) {
          service.load();
      }
    }
    

    在HTML中使用异步管道来管理所有订阅

    <div *ngIf="loading$ | async else elseBlock">loading ...</div>
    <ng-template #elseBlock>
        <div *ngIf="users$ | async as users">
            <div *ngFor="let user of users">
                Email: {{user.email}}
            </div>
        </div>
    </ng-template>
    

    在您的服务中使用RxCache安装“npm install ngx-rxcache --save”并从'ngx-rxcache'导入;

    @Injectable()
    export class UsersService {
      constructor(private http: Http, private cache: RxCacheService) { }
    
      private userCache = this.cache.get<User[]>({
          id: '[User] users',
          construct: () => this.http.get<User[]>('/rest/users'),
          save: user => this.http.post<User[]>("/rest/users", user)
      });
    
      users$ = this.userCache.value$;
      loading$ = this.userCache.loading$;
      saving$ = this.userCache.saving$;
    
      create(user: User, saved?: (response: any, value: any) => void) {
          this.userCache.save(user, saved);
      }
    
      load() {
          this.userCache.load();
      }
    }
    
    // Use interfaces over classes
    export interface User {
      username: string;
      email: string;
      password: string;
    }
    

    并在兄弟组件中

    @Component({
      selector: 'app-form',
      templateUrl: './form.component.html',
      styleUrls: ['./form.component.css']
    })
    export class FormComponent implements OnInit {
      constructor(private service: UsersService, private router: Router) { }
    
      saving$ = this.service.saving$;
    
      ngOnInit() {
      }
    
      onSubmit(formValue: any) {
        let user = { username: formValue.username, email: formValue.email, password: formValue.password };
        this.usersService.create(user, (response, value) => {
            // Don't navigate until the save has finished.
            this.router.navigate(['users']);
        });
      }
    
    }
    

    在您的html中,您可以显示保存消息,就像我们在其他组件中加载一样 .

    <div *ngIf="saving$ | async">saving ...</div>
    
  • 1

    您可以使用 BehaviorSubject 来通知订阅它的任何组件 . 这是一种特殊类型的可观察物 . 例如,在您的用户服务中,定义用户(您可以轻松地将其更改为用户列表):

    import {Observable, BehaviorSubject} from 'rxjs/Rx';  // 
    import {User} from "../../models/user";               // Your model
    
    ... inside your class:
    
    private _currentUser = new BehaviorSubject<User>(new User);
    getUser = this._currentUser.asObservable();
    setUser(user: User) { this._currentUser.next(user) }
    

    在组件中,您可以像这样订阅 getUser 主题:

    this.userService.getUser.subscribe(
    user => {
        this.user = user;
    });
    

    这样,多个组件可以订阅此 BehaviorSubject ,并且任何使用 setUser 方法的组件/服务中的任何触发器都可以立即更改这些订阅组件 .

    ... you successfully added a user in your
    ... component, now use the trigger:
    
    this.userService.setUser(this.user);
    

相关问题