针对如何将数据从第三方库回调和firebase传递到AngularJS中的View这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展AngularMaterial2数据表连接到AngularF
针对如何将数据从第三方库回调和firebase传递到AngularJS中的View这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Angular Material 2数据表连接到AngularFire2或Firebase服务?、Angular.js将数据从异步服务传递到范围、angular1学习笔记,里面有angularjs中的view model同步过程、Angular2 Newbie将数据从Parent传递到Child组件等相关知识,希望可以帮助到你。
本文目录一览:- 如何将数据从第三方库回调(firebase)传递到AngularJS中的View(调用第三方接口存入数据库)
- Angular Material 2数据表连接到AngularFire2或Firebase服务?
- Angular.js将数据从异步服务传递到范围
- angular1学习笔记,里面有angularjs中的view model同步过程
- Angular2 Newbie将数据从Parent传递到Child组件
如何将数据从第三方库回调(firebase)传递到AngularJS中的View(调用第三方接口存入数据库)
我正在使用angularjs和firebase上载文件,我正在尝试从控制器传递参数以在state_changed事件内查看。它不起作用,我可以在控制器上打印它,但不能在视图中使用它
这些我用过的代码
// File or Blob named mountains.jpgvar file = "";// Create the file metadatavar metadata = { contentType: ''image/jpeg''};// Upload file and metadata to the object ''images/mountains.jpg''var uploadTask = storageRef.child(''images/'' + file.name).put(file, metadata);// Listen for state changes, errors, and completion of the upload.uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, // or ''state_changed'' function(snapshot) { // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log(''Upload is '' + progress + ''% done''); $scope.progress = progress; switch (snapshot.state) { case firebase.storage.TaskState.PAUSED: // or ''paused'' console.log(''Upload is paused''); break; case firebase.storage.TaskState.RUNNING: // or ''running'' console.log(''Upload is running''); break; } }, function(error) { switch (error.code) { case ''storage/unauthorized'': // User doesn''t have permission to access the object break; case ''storage/canceled'': // User canceled the upload break; ... case ''storage/unknown'': // Unknown error occurred, inspect error.serverResponse break; }}, function() { // Upload completed successfully, now we can get the download URL var downloadURL = uploadTask.snapshot.downloadURL;});<pre>{{progress}}</pre>
答案1
小编典典由于firebase事件发生在AngularJS框架之外,因此对$ scope的更改需要使用$ scope。$
apply()
$scope.$apply(function() { $scope.progress = progress;});
从文档中:
Angular通过提供自己的事件处理循环来修改常规JavaScript流。这将JavaScript分为经典和Angular执行上下文。只有在Angular执行上下文中应用的操作才能受益于Angular数据绑定,异常处理,属性监视等。您可以使用$
apply()从JavaScript输入Angular执行上下文。请记住,在大多数地方(控制器,服务)
$apply
已经由处理事件的指令为您调用。$apply
仅当实现自定义事件回调或 使用第三方库回调时
,才需要显式调用 。
有关更多信息,请参见
- AngularJS开发人员指南-与浏览器事件循环集成
Angular Material 2数据表连接到AngularFire2或Firebase服务?
目前我有这个设置.我的代码工作得很好,没有带有标准Angular设置和代码的表,使用ngFor并从模板创建列表.所以代码使用AngularFire 2从Firebase传递数据.尝试新的md数据表就是问题所在.
首先,模板不会渲染.我知道我已经正确设置了NgModule,所以我怀疑数据源没有连接并且创建了这个错误.这是Chrome控制台中的错误.
Template parse errors: Can't bind to 'dataSource' since it isn't a kNown property of 'md-table'. 1. If 'md-table' is an Angular component and it has 'dataSource' input,then verify that it is part of this module.
我的members- search.component.html看起来与官方文档相同,只是我更改了模板绑定:
<md-table #table [dataSource]="dataSource"> <ng-container cdkColumnDef="memberName"> <md-header-cell *cdkHeaderCellDef> Name </md-header-cell> <md-cell *cdkCellDef="let row"> {{member.firstName}} {{ member?.lastName }} </md-cell> </ng-container>
members-search.component.ts包含以下相关部分:
import { DataSource } from '@angular/cdk'; @Injectable() export class MembersAdminService { private members$: FirebaseListObservable<Member[]>; private dataSource: DataSource<any>; constructor( private af: AngularFireDatabase,@Inject(FirebaseApp) fb) { this.members$= af.list('Members'); }
我将这些数据表函数放入members-search.service.ts中的工作代码中,并在connect()中使用了与我在其他地方使用的相同代码.
// md table dataSource functions. public connect(): FirebaseListObservable<any> { return this.af.list('Members',{ query: { orderByChild: 'lastName' } }); // return this._exampleDatabase.dataChange; } public disconnect() {}
数据表docs和plunker在组件中创建了一个数据源和数据库,但是如果我已经拥有Firebase,那么大多数情况似乎都没有必要.我正在学习所有这些,所以我在任何事情上都不是专家,也许我错过了一些东西.
如果您之前没有进入这个新设置,那么这里是文档. md表构建在cdk表的顶部,为cdk表提供样式.
https://material.angular.io/components/table/overview
https://material.angular.io/guide/cdk-table
成员admin.service.ts
import { AngularFireDatabase,FirebaseListObservable } from 'angularfire2/database'; import { FirebaseApp } from 'angularfire2'; import { Inject,Injectable } from '@angular/core'; import { MemberModel } from './member-admin.model'; import { SuccessService } from '../../../shared/success.service'; // Data Table imports. import { MdPaginator } from '@angular/material'; import { DataSource } from '@angular/cdk'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import 'rxjs/add/operator/startWith'; import 'rxjs/add/observable/merge'; import 'rxjs/add/observable/combineLatest'; import 'rxjs/add/operator/map'; @Injectable() export class MembersAdminService { private membersData$: FirebaseListObservable<MemberModel[]>; constructor( public af: AngularFireDatabase,private successService: SuccessService,// For Create and Update functions. @Inject(FirebaseApp) fb) { this.membersData$= af.list('Members'); } // ... CRUD stuff not relevant to the MD Table ... // *** MD DATA TABLE SERVICES. *** @Injectable() export class MemberDatabase { /* Stream that emits whenever the data has been modified. */ public dataChange: BehaviorSubject<MemberModel[]> = new BehaviorSubject<MemberModel[]>([]); get data(): MemberModel[] { return this.dataChange.value; } // Connection to remote db. private database = this.memberAdminService.af.list('Members',{ query: { orderByChild: 'lastName' } }); public getMembers(): FirebaseListObservable<MemberModel[]> { return this.database; } constructor(private memberAdminService: MembersAdminService) { this.getMembers() .subscribe(data => this.dataChange.next(data)); } } @Injectable() export class MembersAdminSource extends DataSource<MemberModel> { constructor( private memberDatabase: MemberDatabase,private paginator: MdPaginator) { super(); } /** Connect function called by the table to retrieve one stream containing the data to render. */ connect(): Observable<MemberModel[]> { const displayDataChanges = [ this.memberDatabase.dataChange,this.paginator.page,]; return Observable .merge(...displayDataChanges) // Convert object to array with spread Syntax. .map(() => { const dataSlice = this.memberDatabase.data.slice(); // Data removed from viewed page. // Get the page's slice per pageSize setting. const startIndex = this.paginator.pageIndex * this.paginator.pageSize; const dataLength = this.paginator.length; // This is for the counter on the DOM. return dataSlice.splice(startIndex,this.paginator.pageSize); }); } disconnect() {} }
全members.component.ts
在ngOnInit和类属性中进行了一些重构.
import { Component,OnInit,ViewChild } from '@angular/core'; import { Router } from '@angular/router'; import { Subject } from 'rxjs/Subject'; // For MD Data Table. import { MdPaginator } from '@angular/material'; import { MembersAdminService,MembersAdminSource,MemberDatabase } from './member-admin.service'; import { ConfirmService } from '../../../shared/confirm.service'; import { MemberModel } from './member-admin.model'; @Component({ selector: 'app-all-members',templateUrl: './all-members.component.html' }) export class AllMembersComponent implements OnInit { membersData: MemberModel[]; private result: boolean; allMembers: MemberModel[]; // For search startAt = new Subject(); endAt = new Subject(); lastKeypress: 0; // For MD data table. // private memberDatabase = new MemberDatabase(); // Requires a param but? Moved to constructor. private dataSource: MembersAdminSource | null; private displayedColumns = [ 'firstName','lastName','mainSkillTitle','mainSkills','delete','key' ]; @ViewChild(MdPaginator) paginator: MdPaginator; public dataLength: any; // For member counter on DOM. constructor( private membersAdminService: MembersAdminService,private memberDatabase: MemberDatabase,private router: Router,private confirmService: ConfirmService ) {} ngOnInit() { this.memberDatabase.getMembers() .subscribe(members => { this.dataSource = new MembersAdminSource(this.memberDatabase,this.paginator); this.dataLength = members; }); }
全members.component.html
注意我在行中有按钮用于删除和编辑,它们工作正常.诀窍是您需要隐藏列中的数据库密钥.
<md-table #table [dataSource]="dataSource"> <!-- First Name Column --> <ng-container cdkColumnDef="firstName"> <md-header-cell *cdkHeaderCellDef> First Name </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.firstName}} </md-cell> </ng-container> <!-- Las Name Column --> <ng-container cdkColumnDef="lastName"> <md-header-cell *cdkHeaderCellDef> Last Name </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.lastName}} </md-cell> </ng-container> <!-- Title Column --> <ng-container cdkColumnDef="mainSkillTitle"> <md-header-cell *cdkHeaderCellDef> Title </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.mainSkillTitle}} </md-cell> </ng-container> <!-- Main Skills Column --> <ng-container cdkColumnDef="mainSkills"> <md-header-cell *cdkHeaderCellDef> Main Skills </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.mainSkills}} </md-cell> </ng-container> <!-- Delete Buttons Column --> <ng-container cdkColumnDef="delete"> <md-header-cell *cdkHeaderCellDef> Delete / Edit </md-header-cell> <md-cell *cdkCellDef="let row"> <button (click)="deleteMember(row.$key)">Delete</button> <button (click)="goToDetailPage(row.$key)">Edit</button> </md-cell> </ng-container> <!-- Database key Column --> <ng-container cdkColumnDef="key"> <md-header-cell *cdkHeaderCellDef> Key </md-header-cell> <md-cell *cdkCellDef="let row"> {{row.$key}} </md-cell> </ng-container> <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row> <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row> </md-table> <md-paginator #paginator [length]="dataLength?.length" [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5,10,25,100]"> </md-paginator>
Angular.js将数据从异步服务传递到范围
我有类似的服务
app.factory(''geolocation'', function ($rootScope, cordovaReady) { return { getCurrentPosition: cordovaReady(function (onSuccess, onError, options) { navigator.geolocation.getCurrentPosition(function () { var that = this, args = arguments; if (onSuccess) { $rootScope.$apply(function () { onSuccess.apply(that, args); }); } }, function () { var that = this, args = arguments; if (onError) { $rootScope.$apply(function () { onError.apply(that, args); }); } }, options); }), getCurrentCity: function (onSuccess, onError) { this.getCurrentPosition(function (position) { var geocoder = new google.maps.Geocoder(); geocoder.geocode(options,function (results, status) { var city = address_component.long_name; }); }); } }});
我想从控制器做类似
function MainCtrl($scope, geolocation) { geolocation.getCurrentCity(function(city){ $scope.city = city; });};
getCurrentPosition可以正常工作,并且城市也已确定,但是我不知道如何在控制器中访问城市。
怎么了?
调用getCurrentCity时,它将调用getCurrentPosition来确定gps坐标。该坐标作为参数传递给onSuccess方法,对吗?因此,这与我要在getCurrentCity方法中执行的操作完全相同,但我不知道如何做。异步地理编码器检索了城市,我想将新数据应用于onSuccess方法。
有任何想法吗?
答案1
小编典典您正在处理回调和异步请求。因此,您应该使用$ q服务。只需使用$
rootScope和cordovaReady依赖项将其注入您的服务即可。并像这样向您的功能添加承诺
getCurrentCity: function () { var deferred = $q.defer(); this.getCurrentPosition(function (position) { var geocoder = new google.maps.Geocoder(); geocoder.geocode(options,function (results, status) { var city = address_component.long_name; $rootScope.$apply(function(){ deferred.resolve(city); }); }); }); return deferred.promise;}
然后在您的控制器中,执行以下操作来处理承诺。
function MainCtrl($scope, geolocation) { geolocation.getCurrentCity().then(function(result) { //result === city $scope.city = result; //do whatever you want. This will be executed once city value is available }); };
angular1学习笔记,里面有angularjs中的view model同步过程
这算是一篇个人对angularjs的理解笔记吧,这里有view model的同步过程,写给大家看看吧,现在就让我们一起进入本篇文章吧
事情起源于在项目中遇到的一个小问题:项目中需要一个输入框输入卖出产品数量,并且在用户输入后根据输入数据计算手续费。很自然的我用了ng-model和ng-change,并且一般情况下没什么问题。问题是:输入框下还有一个按钮是全部卖出,点击这个按钮程序会自动设置卖出额。但实际上这时程序并没有计算手续费。
经过排查并查阅文档之后,发现是ng-change的问题。Angular关于ng-change的官方文档的提示是:
The expression is not evaluated when the value change is coming from the model.
ng-change的源码也很简单:
var ngChangeDirective = valueFn({ restrict: ''A'', require: ''ngModel'', link: function(scope, element, attr, ctrl) { ctrl.$viewChangeListeners.push(function() { scope.$eval(attr.ngChange); }); } });
从中我们也可以看出ng-change只做了view到model的监听。所以当我们直接在js中修改ng-model的变量时并不会触发ng-change。
问题找到了,解决方案也不难,放弃ng-change,改用$watch就行了。
但是就这么结束了吗?一个变量从view变化开始到同步更新到model到底经历了什么呢?反过来呢,是一样的吗?
所以我又去看了看ng-model的源码,并没有什么收获,不过意外的了解到了这么个点:
ng-change是在model值变化之前执行的。ng-model源码中有这么个函数:
function setupModelWatcher(ctrl) { // model -> value // !!!Note: we cannot use a normal scope.$watch as we want to detect the following: // !!!1. scope value is ''a'' // !!! 2. user enters ''b'' // !!!3. ng-change kicks in and reverts scope value to ''a'' // -> scope value did not change since the last digest as // ng-change executes in apply phase // !!!4. view should be changed back to ''a'' ctrl.$$scope.$watch(function ngModelWatch(scope) { var modelValue = ctrl.$$ngModelGet(scope); // if scope model value and ngModel value are out of sync // This cannot be moved to the action function, because it would not catch the // case where the model is changed in the ngChange function or the model setter if (modelValue !== ctrl.$modelValue && // checks for NaN is needed to allow setting the model to NaN when there''s an asyncValidator // eslint-disable-next-line no-self-compare (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue) ) { ctrl.$$setModelValue(modelValue); } return modelValue; }); }
里面的注释解释了为什么变量model值的修改要在ng-change之后,因为ng-change中很可能会把变量的值又修改回去,这样变量值事实上就并没改变(写api真的是什么情况都要考虑到啊!!)。关于这一点,以及前面的问题这里有一个demo代码:http://php.cn/course/47.html
既然看源码没什么收获,那么就去网上搜搜文章看看吧。这个过程中找到一篇很好的文章,这篇文章介绍了
$formatters,$parsers,$render以及$setViewValue。这里就不再介绍了,如果需要学习,原文在这里:http://php.cn/course/47.html
在学习$setViewValue时也发现一个很容易被坑的点:在调用$setViewValue时,如果参数是引用变量,那么如果引用变量地址没变,则这个变量被认为没有改变,如 var map = [‘er’, ’tr’];那么map.pop();之后$setViewValue并不认为map值改变了。关于这个具体可以看我对这个问题的回答。(想看更多就到PHP中文网AngularJS开发手册中学习)
ng-model也有这个问题,这个在ng-model源码注释中可以看到:
However, custom controls might also pass objects to this method. Inthis case, we should make a copy of the object before passing it to$setViewValue. This is because ngModel does not perform a deepwatch of objects, it only looks for a change of identity.If you only change the property of the object then ngModel will notrealize that the object has changed and will not invoke the $parsersand $validators pipelines.
从上面也可以看到其实一个变量的更新由view到model和model到view不止$formatters和$parsers管道,那么还有哪些呢?
在查了一圈资料后找到一个很清晰的解释:https://stackoverflow.com/que...,大家其实只需要看问题的回答,问题实在太长了。。。
这个回答中有个demo链接,我copy了一下并做了写小修改放在这个地址了:http://php.cn/course/47.html,这个demo很清晰的显示了变量更新的过程,细节就不再累述了,这里只把结果总结如下:
从model到view:
model值修改 ----> $formatters管道 ----> $render函数 ----> $validators ----> $watch函数
从view到model:
view值修改 ----> $setViewValue函数----> $parsers管道 ----> $validators ----> $viewChangeListener函数 ----> $watch函数
我们也可以直接调用$setViewValue函数去直接改变$viewValue 的值,流程会和上面一样。
注意在使用$setViewValue时一定要警惕参数是引用变量的情况,这个坑在上文也已经提到了。
本文没有具体介绍$formatters 和 $parsers 管道,关于这部分可以参考文中给出的链接
好了,本篇文章到这就结束了(想看更多就到PHP中文网AngularJS使用手册中学习),有问题的可以在下方留言提问。
以上就是angular1学习笔记,里面有angularjs中的view model同步过程的详细内容,更多请关注php中文网其它相关文章!
Angular2 Newbie将数据从Parent传递到Child组件
在父代码中,我有以下内容:
<div*ngFor="let movie of movies; let i = index;"> <movie-card [movie]="movie"></movie-card> </div>
在我的movie-card.component.ts文件中,我有以下代码:
import { Component,Input } from '@angular/core'; @Component({ selector: 'movie-card',templateUrl: './movie-card.component.html',styleUrls: ['./movie-card.component.css'] }) export class MovieCardComponent { @input() movie: Object; constructor() { console.log('movie : ' + this.movie); } }
Chrome控制台的输出是:
20 movie : undefined movie-card.component.ts:15
但是在movie-card.component.html中
{{movie.Name}}
html将输出电影名称.
我想将movie.Name值发送到我的服务中.
_anatomyService.getimage(this.movie.Name);
但是电影的价值是不确定的.我不明白的是什么?
先感谢您.
解决方法
import { Component,styleUrls: ['./movie-card.component.css'] }) export class MovieCardComponent { @input() set movie(movie: Object){ console.log(movie); //asign it to a value or do something with it } }
关于如何将数据从第三方库回调和firebase传递到AngularJS中的View的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Angular Material 2数据表连接到AngularFire2或Firebase服务?、Angular.js将数据从异步服务传递到范围、angular1学习笔记,里面有angularjs中的view model同步过程、Angular2 Newbie将数据从Parent传递到Child组件的相关知识,请在本站寻找。
本文标签: