【问题标题】:Angular 13 - Data is accessible inside component, but does not show on the html pageAngular 13 - 数据可在组件内部访问,但未显示在 html 页面上
【发布时间】:2022-01-24 06:26:44
【问题描述】:

所以,我现在正在学习 Angular,并尝试做一个 CRUD 应用程序。几乎一切正常,除了尝试使用 ID 获取数据时,我可以访问 component.ts 文件中的所有数据,但同样不会呈现到 html 文件中。这是我尝试过的:-

edit-to.component.ts

export class EditTodoComponent implements OnInit {

private tid: number = 0;

  public Todo:TodoModel= null ;
  public desc:string='';
  public title:string='';
  public id:number;

  constructor(private route: ActivatedRoute, private http:HttpClient) { }

  ngOnInit(): void {
    this.route.paramMap.subscribe(all_params =>{
      this.tid = parseInt(all_params.get('id'))
      //console.log( all_params.get('id'))
      //console.log( this.tid );
    });

    this.getTodoFromId(this.tid)


  }

   getTodoFromId(id){
    //console.log("id="+id)
     this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/'+id).subscribe((data) =>{
      console.log("response in angular= \n");
      this.Todo = data[0]
      

      console.log(this.Todo.todo_title) //-> This one works

}
editOnSubmit(form:NgForm){
  //something here
}

edit-todo.component.html

 <div class="col-md-12">
    <form (ngSubmit)="editOnSubmit(todoForm)" #todoForm="ngForm">
      <input type="text" class="form-control" id="todo_id" [(ngModel)]="id" name="todo_id" value="1">
      <div class="mb-3">
        <label for="todo_title" class="form-label">Title</label>

        <input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}">  //-> This one does not work.

      </div>
      <div class="mb-3">
        <label for="label" class="form-label">Description</label>
        <textarea  class="form-control" id="todo_description" [(ngModel)]="desc" name="desc" ></textarea>
      </div>

      <button type="submit" class="btn btn-success">Edit To Do</button>
    </form>
  </div>
</div>

分离出来,

来自 edit-to.component.ts :-

console.log(this.Todo.todo_title) 有效

但来自 edit-todo.component.html

&lt;input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}"&gt; 不起作用

【问题讨论】:

    标签: node.js angular


    【解决方案1】:

    定义一个 BehaviorSubject 类型的属性。

    isAvailableData = new BehaviorSubject<boolean>(true);
    

    然后你订阅数据的地方设置为true。

    getTodoFromId(id){
    //console.log("id="+id)
     this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/'+id).subscribe((data) =>{
      console.log("response in angular= \n");
      this.Todo = data[0];
    
      this.isAvailableData.next(true);
    
      console.log(this.Todo.todo_title) //-> This one works
    

    }

    然后在你的 HTML 中添加 ngIf 到 col-md-12 div:

    <div class="col-md-12" *ngIf="(isAvailableData | async)">
    <form (ngSubmit)="editOnSubmit(todoForm)" #todoForm="ngForm">
      <input type="text" class="form-control" id="todo_id" [(ngModel)]="id" name="todo_id" value="1">
      <div class="mb-3">
        <label for="todo_title" class="form-label">Title</label>
    
        <input type="text" class="form-control" id="todo_title" [(ngModel)]="title" name="title" value="{{ Todo.todo_title}}">  //-> This one does not work.
    
      </div>
      <div class="mb-3">
        <label for="label" class="form-label">Description</label>
        <textarea  class="form-control" id="todo_description" [(ngModel)]="desc" name="desc" ></textarea>
      </div>
    
      <button type="submit" class="btn btn-success">Edit To Do</button>
    </form>
    

    另外,您在表单中犯了错误,输入应如下所示:

    而且没有必要为 id、title、...定义一个属性 这些是 todo 对象的属性

     <label for="todo_title" class="form-label">Title</label>
    
      <input type="text" class="form-control" id="todo_title" [(ngModel)]="Todo.todo_title" name="todo_title" #todo_title="ngModel">
    

    【讨论】:

    • 我正在尝试不使用 Rxjs。
    • 最佳实践是使用 Rxjs。你也可以使用布尔类型 public isAvailableData: boolean;
    • 并将 ngIf 更改为:*ngIf="isAvailable"
    【解决方案2】:

    这是因为您在同一输入字段上配置了一个 ngModel 和一个值

    在这种情况下,ngModel 优先于 value 属性

    要修复它,您可以在 ngOnInit 中初始化标题

    this.title = this.Todo.todo_title; 
    

    在您的情况下,您等待来自 http 请求的回复,因此在 hte http 回复之后进行初始化:

    getTodoFromId(id){
         this.http.get<{data: any}>('http://localhost:3000/api/todos/get_todo_from_id/'+id).subscribe((data) =>{
          console.log("response in angular= \n");
          this.Todo = data[0]
          this.title = this.Todo.todo_title;
    
          console.log(this.Todo.todo_title);
    
    }
    

    【讨论】:

    • 让我试试这个。但是,您提出的方法,如果输入字段的数量更多,比如 20 个左右怎么办?有没有更好的方法?
    • ngModel 可以是对象的属性。如果你有一个大结构,我建议你在模型对象中复制这个对象并在你的输入中使用它。获取 Todo 副本并分配 [(ngModel)] = todoCopy.todo_title
    • 我尝试了这个方法,但是虽然我可以访问getTodoFromId() 中的数据,但我无法在ngOnInit 中访问它。当我尝试时,this.getTodoFromId(this.tid) console.log("Here"+this.Todo.todo_title)ngOnInit 内,它说 todo_title 不是 Todo 的已知属性
    • 是的,您在 getTodoFromId 方法中有一个 http.get,因此您必须在 http 回复后设置数据
    • 我做到了。但是,我无法访问 ngOnInit 或 html 页面中的数据
    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    相关资源
    最近更新 更多