【问题标题】:event after firebase is loaded into the DOMfirebase 加载到 DOM 后的事件
【发布时间】:2016-03-26 21:44:12
【问题描述】:

我想根据来自 firebase 的值更改输入字段中字体的颜色。

在 jquery 中我使用 $(document).ready() 但我的代码在 firebase 数据加载到 dom 之前触发。

我已经恢复使用 setTimeout() 来给 dom 足够的时间来加载,但这并不是真正的方法。

数据附加到 DOM 后一定有事件触发?

app.controller('myCtrl', function($scope, $stateParams, $firebaseObject) {

      var ref = new Firebase('xxxxxxxxx');
      $scope.Details = $firebaseObject(ref);

//what I really need is, "tell me when the firebase object is loaded to the DOM 
//so I can do my stuff"


    setTimeout(function(){ 
      if($("#idInput").val() ==='foo'){
      $("#idInput").css("color", "red");
      }
    }, 500);

});

【问题讨论】:

    标签: javascript jquery angularjs firebase angularfire


    【解决方案1】:

    如果您需要使用来自$firebaseObject 的数据,请使用$loaded()

    $scope.Details = $firebaseObject(ref);
    $scope.Details.then(function(data) {
       // loaded data here
    });
    

    否则,当数据加载完毕时,$firebaseObject 会通知$digest 循环。

    另一种策略是在路由器中使用resolve 将数据加载到控制器中。这更简洁,因为您不需要解开承诺。

    .config(function($stateProvider) {
      $stateProvider.state('home', {
        controller: 'myCtrl',
        template: 'myTemplate.html',
        resolve: {
          details: function($firebaseObject, $stateParams) {
            var ref = new Firebase('xxxxxxxxx');
            var childRef = ref.child($stateParams.id);
            return $firebaseObject(childRef).$loaded();
          }
        }
      });
    })
    

    然后在您的控制器中解析数据:

    .controller('myCtrl', function($scope, details) {
      $scope.Details = details; // totally available to use
    })
    

    Read the docs for more information on resolving data with routing and AngularFire.

    【讨论】:

    • 我真的很喜欢这样,但我在 firebase URL var ref = new Firebase('xxxxxxxx' + $scope.currentState + ''); 末尾附加了 $stateParams而且我的 app.config 并不喜欢我尝试获取 $scope.currentState = $stateParams.id;在状态配置中
    • 你也可以注入 $stateParams
    • 我已更新我的答案,以反映您如何在 resolve 对象中使用 $stateParams
    【解决方案2】:

    您似乎不需要在这里使用setTimeout,您可以使用ng-class 指令在输入值更改时应用CSS。

    HTML

    <input id="idInput" ng-model="idInput" ng-class="{ 'red': idInput == 'foo' }"/>
    

    CSS

    .red {
       color: red;
    }
    

    如果您真的有兴趣在通过$firebaseObject(ref) 加载数据后做某事,那么您应该使用$loaded 方法而不是$firebaseObject,一旦加载数据就会调用该方法。将更喜欢使用$timeout 而不是setTimeout 通过运行摘要循环来使同步范围变量与html 绑定。此外,不要从控制器进行 DOM 操作,它被视为反模式。

    代码

    $scope.Details = $firebaseObject(ref);
    $scope.Details.$loaded()
    .then(function(data) {
        //do some code
        $timeout(function(){ 
            //you shouldn't use DOM manipulation from angular controller.
            //if($("#idInput").val() ==='foo'){
            //$("#idInput").css("color", "red");
          }
        }, 500);
    })
    

    【讨论】:

    • 我试过这个,数据显示在控制台中,但是在警报触发之前数据没有附加到dom $scope.Details.$loaded() .then(function(data) { //做一些代码 console.log(data); alert(33); });
    • ng-class="{ 'red': idInput == 'foo' }" 这确实很好,但是当我尝试 ng-class="{ 'red': idInput == 'foo' , 'red': idInput == 'bar'}" 它只计算最后一个表达式 "bar" 顺便说一句:我真的很感谢你的帮助
    • 感谢它对最新变量的明显分配将在 javascript 中得到优先考虑。如果你想达到你正在尝试的相同目标,你可以这样做ng-class="{ 'red': idInput == 'foo' || 'bar'}
    • @PankajParker 我试过了,它抛出的论点是真的“foo”“bar”“a”“b”等等......所以它一直都是真的
    • @Jason 抱歉,这是我的错……语法错误,应该是 ng-class="{ 'red': (idInput == 'foo' || idInput == 'bar')}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2013-01-24
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多