【问题标题】:AngularJS: weird behavior with the 2-way binding (ng-repeat)AngularJS:2 向绑定(ng-repeat)的奇怪行为
【发布时间】:2016-12-12 17:40:05
【问题描述】:

我在 Firebase 应用程序中使用 AngularJS,并且我有一个函数,我可以在其中执行一些内部连接以获取一些数据。更多details here。从 firebase api 获得响应后,我创建了一个对象并将其推送到一个数组(范围变量)中。我在调试中看到数据已被检索并且 $scope 变量已正确填充。问题是它没有显示在 ng-repeat 中。

我的功能:

$scope.getMessagesByRegion = function(regionId){

    console.log('Function start');
    var rootRef = firebase.database().ref();
    var regionMessagesRef = rootRef.child("region_messages/"+ regionId);
    $scope.messages_by_region = []; // Here I reset the scope variable

    regionMessagesRef.on('child_added', function(rmSnap) {

        var messageRef = rootRef.child("messages/"+rmSnap.key);
        messageRef.once('value').then(function(msgSnap){

            var msg = {
                key : msgSnap.key,
                name : msgSnap.val().name,
                type : $scope.getTypeName(msgSnap.val().type),
                show_only_once : rmSnap.val().show_only_once,
                pre_requisite_message : rmSnap.val().pre_requisite_message
            }
            console.log(msg); // here I see the object in the console. it is OK
            $scope.messages_by_region.push(msg); // pushing the item
            console.log('----------------');
            console.log($scope.messages_by_region);
        })

    });
}

我的 HTML:

            <table class="table">
                <thead>
                <tr>
                    <th>Message name</th>
                    <th>Type</th>
                    <th>Show only once</th>
                    <th>Pre requisite</th>
                </tr>
                </thead>
                <tbody>
                <tr ng-repeat="msg in messages_by_region">
                    <td ng-bind="msg.name"></td>
                    <td ng-bind="msg.type"></td>
                    <td ng-bind="msg.show_only_once"></td>
                    <td ng-bind="msg.pre_requisite_message"></td>
                </tr>
                </tbody>
            </table>

这是我在控制台中看到的:

问题是即使数组中有一个对象,它也不会显示在视图中。就像有一个空数组设置为$scope.messages_by_region 变量

我很难弄清楚我做错了什么。你能看出我的函数有什么问题吗?

感谢您的帮助。

【问题讨论】:

  • 尝试添加 console.log($scope.messages_by_region);到一个测试函数并进行 ng-click 调用这个函数,看看会发生什么。您还看到控制台中有任何错误吗?
  • 您是否尝试过不使用 ng-bind 指令? &lt;td&gt;{{msg.name}}&lt;/td&gt;

标签: javascript angularjs


【解决方案1】:

试试,

$scope.$apply(function(){
 $scope.messages_by_region.push(msg);
});

或者,

$scope.messages_by_region.push(msg);
$scope.$apply();

【讨论】:

  • 成功了!谢谢!应用接收函数,使其仅检查该函数内部受影响的值?
  • 你调用了一个非角度函数messageRef.once,因此你必须告诉角度某个 $scope 变量发生了变化。
【解决方案2】:

由于您使用的是异步函数(使用 firebase API),您应该告诉 Angular 刷新 HTML;

使用

$scope.$diggest()

您可以在https://www.sitepoint.com/understanding-angulars-apply-digest/找到更多信息

【讨论】:

  • 谢谢!我不得不使用 $scope.$apply()
【解决方案3】:

当您执行异步调用时,您需要告诉 angular 使用 $apply 调用刷新值的更改,您可以这样做:

$scope.getMessagesByRegion = function(regionId) {

  console.log('Function start');
  var rootRef = firebase.database().ref();
  var regionMessagesRef = rootRef.child("region_messages/" + regionId);
  $scope.messages_by_region = []; // Here I reset the scope variable

  regionMessagesRef.on('child_added', function(rmSnap) {

    var messageRef = rootRef.child("messages/" + rmSnap.key);
    messageRef.once('value').then(function(msgSnap) {
        var msg = {
          key: msgSnap.key,
          name: msgSnap.val().name,
          type: $scope.getTypeName(msgSnap.val().type),
          show_only_once: rmSnap.val().show_only_once,
          pre_requisite_message: rmSnap.val().pre_requisite_message
        }

      $scope.$apply(function() {
        console.log(msg); // here I see the object in the console. it is OK
        $scope.messages_by_region.push(msg); // pushing the item
        console.log('----------------');
        console.log($scope.messages_by_region);
      });
    });
  });
}

有关此行为的更多信息,您还可以阅读描述该问题的文章here

【讨论】:

  • 很高兴它有帮助(y)
猜你喜欢
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多