Firebase 3 向数据绑定,采用 ControllerAs 语法

Firebase 3-way data binding with ControllerAs syntax

本文关键字:采用 ControllerAs 语法 数据绑定 Firebase      更新时间:2023-09-26

我正在努力获得与Firebase和Angularfire的3向数据绑定。你可以看到我在Plunker中得到了什么:http://plnkr.co/edit/RGA4jZK3Y6n4RkPCHK37

应用.js

angular.module('ideaBattle', ["firebase"]);

服务

angular
    .module('ideaBattle')
    .constant('FBURL', 'https://ideabattle.firebaseio.com/')
    .service('Ref', ['FBURL', Firebase])
    .factory('dataBank', function(Ref, $firebase) {
        return $firebase(Ref).$asArray();
    });

控制器

angular
    .module('ideaBattle')
    .controller('ideaListCtrl', displayIdeas);
displayIdeas.$inject = ['dataBank'];
function displayIdeas(dataBank){
    var vm = this;
    vm.ideas = dataBank;
    vm.upVote = function(idea){
        vm.ideas[idea.id].votes++;
    };
}

HTML

<div ng-controller="ideaListCtrl as vm">
    <div ng-repeat="idea in vm.ideas | orderBy: '-votes'">
        <div>
            <h2>{{idea.name}}</h2>
            <p>{{idea.desc|limitTo: 190}}</p>
            <span class="btn" ng-click="vm.upVote(idea)">Vote! <span class="badge"> {{idea.votes}}</span></span>
        </div>
    </div>
</div>

普伦克版本:http://plnkr.co/edit/RGA4jZK3Y6n4RkPCHK37

的作用是,它从 firebase 获取数据并正确显示,但是当我按下按钮调用 upVote 函数时,它只会在本地更新。我知道为什么它只能在本地工作,但我不知道如何让它在 Firebase 中也更新。

我已经尝试过$bindTo,但据我了解,它需要$scope才能工作,并且我正在尝试使用"控制器即 vm"模式而不注入$scope。

谁能告诉我怎么咬它?

tl;dr; — 3 向数据绑定不适用于 ControllerAs 语法。bindTo方法需要$scope

您可以将 AngularFire 与 ControllerAs 语法一起使用,但不能将其与 Controller $bindTo As 一起使用。

$bindTo$scope有很强的依赖性,没有它就会崩溃。

如果你想要一个将AngularFire与ControllerAs语法一起使用的例子,请查看这个Plunker演示

  angular.module('app', ['firebase'])
  // constant for the Firebase we're using
  .constant('FBURL', 'https://<your-firebase>.firebaseio.com/todos')
  // return the Firebase ref as a service
  .service('Ref', ['FBURL', Firebase])
  // return the Todos from Firebase by returning the
  // array from the factory 
  .factory('Todos', function(Ref, $firebase) {
    return $firebase(Ref).$asArray();
  })
  // inject the Todos and assign them to "this"
  // for the ControllerAs syntax
  .controller('MainCtrl', function(Todos) {
    this.todos = Todos;
  });

John Papa 谈到在每个控制器中使用 var vm = this; 语法而不是$scope的目的之一是让使用$scope成为有意识的选择。在这种情况下,我们需要包括$scope。

我把大卫·伊斯特的 plunkr 放在他的回答中,摆弄了一下。它并不完美,因为它取决于控制器作为值是"vm"。

http://plnkr.co/edit/vLLaa7QJvfryYRD7cZvO?p=preview

  .controller('MainCtrl', function(Todos, $scope) { /* Add $scope */
    var vm = this;
    vm.todos = Todos.all();
    vm.lonelyTodo = Todos.get('-JeNOtYPv7AZmVAoZ1bu');
    vm.lonelyTodo.$bindTo($scope, 'vm.lonelyTodo'); /* Add three way binding */
  });

以 ES6/JS2015 systax 为例,在上面的响应中添加了一些澄清注释。

export class SomeController {
  constructor($firebaseObject, $scope) {
  'ngInject';    
  //using the firebase SDK 3.0 
  let obj = $firebaseObject(firebase.database().ref().child('someKey'));
  // To make the data available in the DOM, assign it to
  // 'this.data' accessible from DOM as $ctrl.data
  this.data = obj;
  // For three-way data bindings, you will still need to inject '$scope'
  // but you can alias your controller on $scope
  obj.$bindTo($scope, '$ctrl.data');
  // Why does this work? 
  // This works because angular 1x puts controllerAs
  // on top of $scope. So '$scope.$ctrl.data' is the same as 'this.data'.
  // Note: $ctrl is the default controllerAs syntax if not specified,
  // just change $ctrl to your defined controllerAs ailias if 
  // specified. 
  }
}