学习可观察和Angular2。我想找出在多个Angular2组件之间共享可观察对象的最佳实践。可以观察到的默认值是不组播。因此,应用程序不同部分的每个订阅都将打开一个新流(再次调用我的API服务器!)。另外,我需要共享该值并获取该可观察值的最新值。我听到有人使用行为主题。但这确实令人困惑,我无法找到一个很好的例子。这是我在authService中处理此问题的方法:
userInfo$: Observable<User>;
this.userInfo$ = this.authInfo$
.switchMap(authInfo => this.findUserByuid(authInfo.$uid)) // finding user info base on authInfo turn or not.
.publishReplay(1).refCount();
Run Code Online (Sandbox Code Playgroud)
在我的Angular2组件中,我这样做:
this.authService.userInfo$.subscribe(user => {
console.log (user);
this.user = user;
})
Run Code Online (Sandbox Code Playgroud)
一切正常。但是我想知道在这种情况下我可以使用行为主题吗?我是否通过在所有组件之间共享userInfo $来做一切正确的事情(所有需要userinfo $的组件都将执行上面的代码来订阅它)?
我有一个3平行的firebase需要.我需要将它们作为单个对象加入.代码如下:
import {Http} from "@angular/http";
import {AngularFireDatabase} from "angularfire2";
import {Thread} from "../model/thread";
import {Message} from "../model/message";
import {Participant} from "../model/participant";
constructor(private http: Http, private db:AngularFireDatabase) { }
loadUserThreads(uid): Observable<AllUserData> {
return Observable.forkJoin([
this.db.list('participant/' + uid + '/threads').first(),
this.db.list('participant/' + uid + '/messages').first(),
this.db.list('participant/' + uid + '/participants').first()
])
.map((data:any[]) => {
let threads: Thread[] = data[0];
let messages: Message[] = data[1];
let participants: Participant[] = data[2];
let AllUserData = {
threads: threads,
messages: messages,
participants: participants
}
return AllUserData; …Run Code Online (Sandbox Code Playgroud) 我尝试用Angular 2学习可观察的编程但是我没有得到一个重要的观点 - 如何在模板级别的(click)事件中传入一个observable中的值(没有在TS文件中订阅observable和将可观察值转换为成员变量).
正如许多Firebase专家所说的那样"尽可能在angular2中使用| async并防止手动订阅!" - 不想手动订阅任务$并将其转换为数组的原因.
例如:
我在组件的TS文件中有这个:
task$: Observable<Task>;
this.task$ = this.tasksService.findTaskById(taskId);
Run Code Online (Sandbox Code Playgroud)
在我的服务中,这是使用AngularFire调用firebase的代码,它返回一个observable:
import {Task} from "../model/task";
constructor(private db:AngularFireDatabase, @Inject(FirebaseRef) fb) {
this.sdkDb = fb.database().ref();
}
findTaskById(id:string):Observable<Task> {
return this.db.object('tasks/' + id).map(task => Task.fromJson(task));
}
Run Code Online (Sandbox Code Playgroud)
在我的模板中,我可以使用异步管道在Angular2中使用没有问题的值,如下所示:
<md-card-title>{{(task$ | async)?.title}}</md-card-title>
Run Code Online (Sandbox Code Playgroud)
但是我有一个按钮,需要在这个任务中的$ id值,如下所示:
<button md-button *ngIf="(authInfo$ | async)?.isLoggedIn()" (click)="deleteTask((task$ | async)?.$key)">Delete</button>
Run Code Online (Sandbox Code Playgroud)
这不会起作用,因为click不允许在表达式中使用管道......而且我不想订阅任务$并将其转换为成员变量(最佳做法是保持任务$ for obserable style RXJS编程?!)
那么我如何得到$ key值,因为它最初不存在,我不能使用异步管道!?
所以我使用标准代码选择如下:
<label class="item item-input item-select" ng-class="{ 'has-error-lr' : postTaskForm.type.$invalid && postTaskForm.$submitted, 'valid-lr' : postTaskForm.type.$valid && postTaskForm.$submitted}">
<div class="input-label"> Video Job Type: </div>
<select ng-model="postTask.type" name="type" ng-required="true">
<option>Commercial</option>
<option>Interview</option>
<option selected>Training Lesson</option>
<option>Live Event Recording</option>
</select>
</label>
Run Code Online (Sandbox Code Playgroud)
在iOs中渲染时,它看起来像这样:
如您所见,顶部确认部分完全缺失.怎么了?如何在本地iO中获取确认按钮?
我正在使用Firebase/AngularFire构建一个Ionic App.我面临着一个棘手的问题:我希望我的ng-repeat能够更好地进行性能优化.我听说最好的方法就是无限滚动.我使用AngularFire在服务/工厂中获取所有数据 - 更具体地说,$ firebaseArray.
我谷歌发现了这个:http://firebase.github.io/firebase-util/#/toolbox/Paginate/example/ionic
问题1:使用Firebase util库的无限滚动是无限滚动服务器端无限滚动还是客户端?这个库是否解决了ng-repeat的性能问题,如下所述:(http://www.alexkras.com/11-tips-to-improve-angularjs-performance/)
问题2:我的firebaseArray实际上需要命令动态计算一个名为distance的变量.我是否仍可以在安全规则中使用.indexOn规则来提高查询性能?(声音不可能,因为距离最初没有存放在火场中)
这是我的代码:我的工厂:taskService.js
var ref = new Firebase(FirebaseUrl);
var tasks = $firebaseArray(ref.child('tasks'));
var Task = {
all: tasks,
getAllTasks: function() {
if (tasks.length == 0) {
tasks = $firebaseArray(ref.child('tasks'));
} else {
tasks = tasks;
}
return tasks;
},
}
Run Code Online (Sandbox Code Playgroud)
我的ng-repeat视图控制器:
$scope.tasks = taskService.getAllTasks();
$scope.tasks.$loaded().then(function(data){
calculateDistance($scope.tasks, $scope.userCurrentLocation);
});
var unwatch = $scope.tasks.$watch(function(event) {
calculateDistance($scope.tasks, $scope.userCurrentLocation);
});
$scope.$on('$ionicView.leave', function(){
// Anything you can think of
unwatch();
});
}
//--------------GeoLocation …Run Code Online (Sandbox Code Playgroud) 这个过程非常混乱。由于 Firebase 现在有一个警告说不支持 CNAME 记录。我以前做的是在 Google Cloud DNS 中设置一个 CNAME 作为 app.mysite.com 并且规范名称指向 Firebase 域,例如。myapp-9afa9.firebaseapp.com。(mysite.com 指向具有 A 记录的其他地方 - 在 Surge.sh 中托管我的静态网站。因此我无法在 Google Cloud DNS 中更改我的 A 记录)。然后在 Firebase 中,我只是连接域并指向 app.mysite.com。然后我在 Google Cloud DNS 中添加 TXT 文件。Firebase 目前可以找到域并进行连接。但它向我显示下一个屏幕说我需要将 A 记录更改为提供的 2 条记录。并警告说不再支持 CNAME 记录...它们都是 GOOGLE 产品!!为什么可以' 我在 Firebase 中不再使用子域作为我的应用程序域了吗?将子域用于 Firebase 的正确工作流程是什么?
firebase google-cloud-platform google-cloud-dns firebase-hosting