为什么条件div不是有角度的

时间:2017-12-30 04:32:21

标签: angular typescript firebase

我在页面中有三个条件 div ,并尝试在某个条件上显示每个div。

<div *ngIf="isAvailable=='true'">
    <form>
            <div class="form-group">
                    <label for="Admin">Deployment Admin</label>
                    <input type="text" class="form-control" id="name" name="name" aria-describedby="name" [(ngModel)]="NewDeployAdmin.name">
                  </div>
            <div class="form-group">
              <label for="exampleInputEmail1">Email address</label>
              <input type="email" class="form-control" id="email" name="email" aria-describedby="email" placeholder="Enter email" [(ngModel)]="NewDeployAdmin.email">

            </div>
            <div class="form-group">
              <label for="exampleInputPassword">Password</label>
              <input type="password" class="form-control" id="paswsword" name="password" placeholder="Password" placeholder="Enter al least 6 character" [(ngModel)]="NewDeployAdmin.password">
            </div>
            <button type="submit" class="btn btn-primary" (click)="fnCreateDeployAdmin()">Submit</button>
    </form>   
</div>

<div *ngIf="isAvailable=='false'">
<button  type="submit" class="btn btn-warning" (click)="fnDisableAccount()">Disable Account</button> | <button  type="submit" class="btn btn-primary" (click)="fnUpdateDeployAdmin()">Reset Credential</button>
</div>

.ts 页面中,我在不同条件下设置 isAvailable ,并希望显示相应的 div 。但它没有用。

我想渲染相应的 div 。以下是我设置 isAvailable

的代码
isDeploymentAdminAvailable(deployment){
  let customQuery = {
    equalTo: this.selectedDeploy.key
  }

  this.authService.fnGetDataUsingCustomQuery(FirebaseDb.firebasedeploymentAdminTable, customQuery).subscribe(
    (rec: any) => {
      rec.forEach((reccord: any) => {
        reccord.key = reccord.$key;
      });
      this.deployAdminData = JSON.parse(JSON.stringify(rec));

    });

  if(this.deployAdminData!=null && Object.keys(this.deployAdminData).length>0){
    return "true";

  }

  return "false";

}

我称之为 isDeploymentAdminAvailable 方法的函数是

deploymentOnClick($event, deployment){ 

    this.isAvailable = 'None';

    this.selectedDeploy = deployment;

     this.isAvailable = this.isDeploymentAdminAvailable(deployment);
}

3 个答案:

答案 0 :(得分:1)

您正在返回"true""false"这些都是评估为true的字符串。删除引号,使其为truefalse,并将isAvailable的类型设置为boolean。并让* ngIf比较isAvailable!isAvailble

老实说,你的代码有很多问题。 Javascript是单线程的,你应该确定你的return语句。即if后面应跟else。我只看到两个条件div ...使用true false或None根本不是一个好主意。名称truefalse意味着二元关系,如果您需要两个以上的选项,则应使用其他术语。

这也是打字稿。您需要输入参数。它们都是any类型。

此外,您将部署传递到isDeploymentAdminAvailable并且不要在任何地方使用它......

同样在javascript中,您需要尽可能使用===!==运算符。

请描述发生的行为。你不是渲染div吗?请将isAvailable更改为布尔值并告诉我发生了什么。在console.log语句和外部使用if并检查控制台以查看满足哪种条件以及是否符合预期。当您将这些更改报告回来时,我会帮助您。

正如@yurzui所说,您的代码问题几乎肯定是您没有使用异步代码。您正在等待firebase返回一个值,然后在返回之前立即检查该值。我想现在代码总是返回"false",因为this.deployAdminData始终是null,因为你没有等待来自firebase的响应,只是直接通过它。

要解决此问题,一种方法是将if条件分离为单独的函数,并在subscribe的末尾调用该函数。

this.authService.fnGetDataUsingCustomQuery(FirebaseDb.firebasedeploymentAdminTable, customQuery).subscribe(
    (rec: any) => {
      rec.forEach((reccord: any) => {
        reccord.key = reccord.$key;
      });
      this.deployAdminData = JSON.parse(JSON.stringify(rec));
      this.isAvailable = this.yourFunctionName(deployAdminData);
    });
}

yourFunctionName(deployAdminData: any) {
  if(deployAdminData !== null && 
  Object.keys(deployAdminData).length > 0) {
    return true;    
  } else { return false; }  
}

也可以编辑:

deploymentOnClick($event, deployment){ 
//this.isAvailable = 'None';
  this.selectedDeploy = deployment;
  this.isDeploymentAdminAvailable(deployment);
}

然后您可以使用*ngIf="isAvailable"。注意我将deployAdminData设置为在参数中键入any。这不是最佳做法,您需要将any替换为数据类型。

答案 1 :(得分:0)

isAvailable无法控制div可见性的基本原因已经给出 - 值应该在订阅中设置。

但很明显,当此标志的类型更改为布尔值时,应用程序会工作。

在我看来,该应用程序的逻辑是,在获取数据之前,您既不显示div的isAvailable === 'None'),然后在获取之后根据返回的值显示一个或另一个div。


根据Angular最佳实践重构

您可能希望将isDeploymentAdminAvailable中的代码推送到authService服务中。

那样

  • 与获取相关的所有逻辑都在一个地方
  • 您的测试会更顺畅
  • 您可以从组件中删除Firebase的依赖关系
  • 将数据和isAvailable属性公开为Observables。

可观察的约定

通常的做法是将$附加到可观察变量的末尾,以明确表示他们需要在模板中使用async管道,或subscribe in ts代码。


为什么可观察变量?

应用程序会在Firebase提取返回值之前很久呈现页面,因此通过在模板中使用可观察变量和async管道,视图将在提取最终返回时自动更新。

此外,Firebase可以在数据库更改时将新值推送到您的应用,因此使用可观察属性,视图会响应这些更改,而无需显式刷新。

我唯一不清楚的是NewDeployAdminthis.deployAdminData之间的关系。
您可能需要添加subscribe()async管道,具体取决于这两个项目的关联方式。


<强> authService.ts

@Injectable()
export class AuthService {

  public deployAdminData$ = new BehaviorSubject({});
  public isAvailable$ = new BehaviorSubject('None');  // initial value set to 'None'

  private fnGetDataUsingCustomQuery(...) {
    ...
  }

  public isDeploymentAdminAvailable(key) {
    let customQuery = {
      equalTo: key
    }
    this.fnGetDataUsingCustomQuery(FirebaseDb.firebasedeploymentAdminTable, customQuery)
      .subscribe(rec => {
        rec.forEach(reccord => reccord.key = reccord.$key );
        const data = JSON.parse(JSON.stringify(rec));  // this may not be needed
        this.deployAdminData$.next(data);
        this.isAvailable$.next( 
          data && Object.keys(data).length ? 'true' : 'false';
        )
      });
}

<强> myComponent.html

<div *ngIf="(isAvailable$ | async)=='true'">
  <form>
    <div class="form-group">
      <label for="Admin">Deployment Admin</label>
      <input type="text" class="form-control" id="name" name="name" 
       aria-describedby="name" [(ngModel)]="NewDeployAdmin.name">
    </div>
    <div class="form-group">
      <label for="exampleInputEmail1">Email address</label>
      <input type="email" class="form-control" id="email" name="email" 
       aria-describedby="email" placeholder="Enter email" 
       [(ngModel)]="NewDeployAdmin.email">
    </div>
    <div class="form-group">
      <label for="exampleInputPassword">Password</label>
      <input type="password" class="form-control" id="paswsword" name="password" 
        placeholder="Password" placeholder="Enter at least 6 characters" 
        [(ngModel)]="NewDeployAdmin.password">
    </div>
    <button type="submit" class="btn btn-primary 
      (click)="fnCreateDeployAdmin()">Submit</button>
  </form>   
</div>

<div *ngIf="(isAvailable$ | async)=='false'">
  <button  type="submit" class="btn btn-warning" 
   (click)="fnDisableAccount()">Disable Account</button>
  <button  type="submit" class="btn btn-primary" 
   (click)="fnUpdateDeployAdmin()">Reset Credential</button>
</div>

<强> myComponent.ts

// Set up observable pipeline that responds to changes in the database.
private isAvailable$ = this.authService.isAvailable$;
private this.deployAdminData$ = this.authService.this.deployAdminData$;

isDeploymentAdminAvailable(deployment) {
  this.authService.isDeploymentAdminAvailable(this.selectedDeploy.key)
}

答案 2 :(得分:-1)

不是在模板中比较和使用表达式,而是直接将值 isAvailable 传递给模板。

<div *ngIf="isAvailable">
   ...
</div>    
<div *ngIf="!isAvailable">
   ...
</div>

我希望它可能会有所帮助。