GVKun编程网logo

如何将数据从第三方库回调(firebase)传递到AngularJS中的View(调用第三方接口存入数据库)

4

针对如何将数据从第三方库回调和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(调用第三方接口存入数据库)

如何将数据从第三方库回调(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 Material 2数据表连接到AngularFire2或Firebase服务?

我希望它只是即插即用:-)我一直在喋喋不休地打了几个小时没有我的小实验工作. md数据表是新的,因此Web上几乎没有神圣的知识.找到将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

我在为MD数据表使用MD Paginator时添加了连接到Firebase的代码. Paginator使服务中的代码更加复杂.大多数代码都在它所属的服务中.请享用!

成员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将数据从异步服务传递到范围

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同步过程

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 -&gt; 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''
  //    -&gt; 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 &amp;&amp;
      // 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组件

Angular2 Newbie将数据从Parent传递到Child组件

我正在查看一个示例Angular 2项目并插入一些代码以尝试从传递给嵌套子组件的影片对象中提取值.

在父代码中,我有以下内容:

<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组件的相关知识,请在本站寻找。

本文标签: