如何使用AngularDart实现firebase列表的主详细信息视图

时间:2017-11-13 15:31:13

标签: angular firebase dart master-detail angular-dart

我想用firebase数据库的列表项上的click函数实现详细主视图。当我在notes_component中使用以下代码定义详细视图组件时,它会绑定数据并填充,但是使用单独的详细视图组件代码不起作用,在调试时会给出结果

<div *ngIf="selectedNote != null">
    <h2>{{selectedNote.title}}</h2>
    <h4>{{selectedNote.subject}}</h4>
    <p>{{selectedNote.text}}</p>
</div>

结果图片

enter image description here

https://webdev.dartlang.org/angular/tutorial/toh-pt2

notes_component.html

<div id="notes" class="mdl-grid">
    <div *ngFor="let note of notes"
         class="mdl-card mdl-cell mdl-cell--4-col section--center mdl-shadow--2dp"
         (click)="onSelect(note)"
         [class.selected]="note === selectedNote">
        <div class="mdl-card__supporting-text note-text">
            <img *ngIf="note.imageUrl != null" [src]="note.imageUrl">
            <h4 class="note-subject">{{note.subject}}</h4>
            <p class="note-title" *ngIf="note.title?.isNotEmpty">{{note.title}}</p>
        </div>

        <div *ngIf="service.user != null" style="visibility: hidden" class="mdl-card__actions note-actions">
            <a (click)="service.removeItem(note.key)" title="Remove note" class="note-remove">
                <i class="material-icons">delete</i>
            </a>
        </div>
    </div>
</div>
<note-detail [note]="selectedNote"></note-detail>

notes_component.dart

import 'package:angular/angular.dart';

import '../../firebase_service.dart';
import '../../model/note.dart';

@Component(
    selector: 'notes',
    templateUrl: 'notes_component.html',
    directives: const [CORE_DIRECTIVES, NgIf, NgFor,])
class NotesComponent implements OnInit {
  final FirebaseService service;
  List<Note> notes = [];
  Note selectedNote;

  NotesComponent(this.service);

  void onSelect(Note note) => selectedNote = note;
  @override
  ngOnInit() {
    notes = service.notes;
  }
}

note.dart library tr_app.item;

const String jsonTagText = "text";
const String jsonTagSubject = "subject";
const String jsonTagTitle = "title";
const String jsonTagImgUrl = "img_url";

class Note {
  int id;
  String key;
  String text;
  String title;
  String subject;
  String imageUrl;

  Note([this.text, this.title, this.subject, this.imageUrl, this.key]);

  static Map toMap(Note item) {
    Map jsonMap = {
      jsonTagText: item.text,
      jsonTagSubject: item.subject,
      jsonTagTitle: item.title,
      jsonTagImgUrl: item.imageUrl
    };
    return jsonMap;
  }
}

firebase_service.dart

import 'dart:html';
import 'package:angular/angular.dart';
import 'package:firebase/firebase.dart' as fb;

import '../src/model/note.dart';

@Injectable()
class FirebaseService {
  final fb.Auth auth;
  final fb.DatabaseReference databaseRef;
  final fb.StorageReference storageRef;
  final List<Note> notes = [];
  fb.User user;
  bool loading = true;

  FirebaseService()
      : auth = fb.auth(),
        databaseRef = fb.database().ref("notes"),
        storageRef = fb.storage().ref("notes");

  init() {
    databaseRef.onChildAdded.listen((e) {
      // Snapshot of the data.
      fb.DataSnapshot data = e.snapshot;

      // Value of data from snapshot.
      var val = data.val();
      // Creates a new Note item. It is possible to retrieve a key from data.
      var item = new Note(
          val[jsonTagText], val[jsonTagTitle], val[jsonTagImgUrl], data.key);
      notes.insert(0, item);
    });

    // Setups listening on the child_removed event on the database ref.
    databaseRef.onChildRemoved.listen((e) {
      fb.DataSnapshot data = e.snapshot;
      var val = data.val();

      // Removes also the image from storage.
      var imageUrl = val[jsonTagImgUrl];
      if (imageUrl != null) {
        removeItemImage(imageUrl);
      }
      notes.removeWhere((n) => n.key == data.key);
    });

    // Sets loading to true when path changes
    databaseRef.onValue.listen((e) {
      loading = false;
    });

    // Sets user when auth state changes
    auth.onIdTokenChanged.listen((e) {
      user = e;
    });
  }

  // Pushes a new item as a Map to database.
  postItem(Note item) async {
    try {
      await databaseRef.push(Note.toMap(item)).future;
    } catch (e) {
      print("Error in writing to database: $e");
    }
  }

  // Removes item with a key from database.
  removeItem(String key) async {
    try {
      await databaseRef.child(key).remove();
    } catch (e) {
      print("Error in deleting $key: $e");
    }
  }

  // Puts image into a storage.
  postItemImage(File file) async {
    try {
      var task = storageRef.child(file.name).put(file);
      task.onStateChanged
          .listen((_) => loading = true, onDone: () => loading = false);

      var snapshot = await task.future;
      return snapshot.downloadURL;
    } catch (e) {
      print("Error in uploading to storage: $e");
    }
  }

  // Removes image with an imageUrl from the storage.
  removeItemImage(String imageUrl) async {
    try {
      var imageRef = fb.storage().refFromURL(imageUrl);
      await imageRef.delete();
    } catch (e) {
      print("Error in deleting $imageUrl: $e");
    }
  }

  // Signs in with the Google auth provider.
  signInWithGoogle() async {
    var provider = new fb.GoogleAuthProvider();
    try {
      await auth.signInWithPopup(provider);
    } catch (e) {
      print("Error in sign in with Google: $e");
    }
  }

  signOut() async {
    await auth.signOut();
  }
}

note_detail_component.html

<div *ngIf="note != null">
    <h2>{{note.title}}</h2>
    <h4>{{note.subject}}</h4>
    <img *ngIf="note.imageUrl != null" [src]="note.imageUrl">
    <p>{{note.text}}</p>
</div>

note_detail_component.dart

import 'package:angular/angular.dart';
import 'package:tr_app/src/firebase_service.dart';
import 'package:tr_app/src/model/note.dart';

@Component(
    selector: 'note-detail',
    templateUrl: 'note_detail_component.html',
    styleUrls: const ['note_detail_component.css'],
    directives: const [
      CORE_DIRECTIVES,
      NgIf,
      NgFor,
    ])
class NoteDetailComponent {

  final FirebaseService service;
  Note note;

  NoteDetailComponent(this.service);

}

2 个答案:

答案 0 :(得分:1)

您需要在模板中写下&#34; ngIf&#34;,而不是&#34; ngif&#34 ;.

答案 1 :(得分:0)

您似乎在浏览器中打开了localhost/.../app/.../note_detail_component.html。这不起作用,因为浏览器不会将您的html视为Angular组件。

如果您运行pub serve并加载组件(可能需要routing),您应该能够按预期看到该组件。