【问题标题】:Strange: AngularJS $scope can show everything in View except Firebase user.email奇怪:AngularJS $scope 可以在 View 中显示除 Firebase user.email 之外的所有内容
【发布时间】:2019-12-22 18:25:44
【问题描述】:

这里发生了一些奇怪的事情还是我错过了其他事情?我有以下模板视图:

user-profile.html

<div id="divUserProfile" ng-controller="userProfileController">
    <h1>User Profile</h1>

    <fieldset>
        <legend>Organizational Information</legend>
        <table>
            <tr>
                <td>
                    <label>Email Address</label>
                    <label id="lblEmail" class="label-value">{{email}}</label>
                </td>
                <td>
                    <label>Contact Number</label>
                    <input id="txtContactNo" type="text" value="{{contactNumber}}">
                </td>
            </tr>
        </table>
    </fieldset>
</div>

index.js

var app = angular.module("myApp", ["ngRoute"])
.config( // $routeProvider config here... )
.controller("userProfileController", function ($scope) {
    console.log("This is userProfileController!");

    firebase.auth().onAuthStateChanged(function (user) {
        if (user) {
            console.log("User = " + user.email); // User does exist and singed in!
            $scope.email = user.email; // Email not rendered!
            console.log("$scope.email = " + $scope.email); // It does contain my email address!
        } else {
            console.log("User = " + user);
        }
    });
});

问题:{{email}} 未渲染!但如果您硬编码 $scope.email = "ee@eee.com";,它就会显示出来!另外,如果你console.log($scope.email),它确实包含我登录的电子邮件地址但从未呈现,为什么???事实上,我在&lt;fieldset&gt; 上填充了更多标签,并且所有标签都使用相同的$scope 正确呈现,除了分配给 Firebase 的user.email 的标签,为什么?我尝试将onAuthStateChanged 替换为var user = firebase.auth().currentUser;,也不起作用。

谁能告诉我它有什么问题?如果您需要我显示更多代码的其他部分,请告诉我,谢谢!

注意:我还注意到谷歌浏览器的自动填充功能已将我的txtContactNo 作为我的登录输入框,不确定这是否与问题有关。

【问题讨论】:

    标签: angularjs firebase firebase-authentication


    【解决方案1】:

    使用 $apply:

    var app = angular.module("myApp", ["ngRoute"])
    .config( // $routeProvider config here... )
    .controller("userProfileController", function ($scope) {
    
        console.log("This is userProfileController!");
    
        firebase.auth().onAuthStateChanged(function (user) {
            if (user) {
                console.log("User = " + user.email); // User does exist and singed in!
                $scope.email = user.email; // Email not rendered!
                //IMPORTANT
                $scope.$apply();
                console.log("$scope.email = " + $scope.email); // It does contain my email address!
            } else {
                console.log("User = " + user);
            }
        });
    });
    

    AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 拆分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。

    您还可以使用$apply() 从 JavaScript 进入 AngularJS 执行上下文。请记住,在大多数地方(控制器、服务),处理事件的指令已经为您调用了 $apply。 仅在实现自定义事件回调或使用第三方库回调时才需要显式调用 $apply。

    有关详细信息,请参阅

    【讨论】:

    • 好的,谢谢您的详细解释,非常感谢! :)
    【解决方案2】:

    每当您修改 Angular 代码之外的内容时——您应该调用 $scope.$apply() 或 $rootScope.$apply() 让 angular 检测更改。

    【讨论】:

      【解决方案3】:

      虽然 @georgeawg 给出的答案很酷,但我后来找到了另一个替代方案,也许是更好的 Angular-Firebase 集成方法,而不使用$scope.$apply(),即AngularFire。似乎需要更多代码,但它可以提供更多与 AngularJS 中的 Firebase 活动相关的其他可靠性和便利性。这是有关如何实现它的简化示例:

      index.html

      <!-- Your Firebase and AngularJS references go here -->
      
      <!-- AngularFire -->
        <script src="https://cdn.firebase.com/libs/angularfire/2.3.0/angularfire.min.js"></script>
      

      index.js 或 app.js

      /* Inject firebase to your Angular module */
      var app = angular.module("myApp", ["ngRoute", "firebase"])
      .config( // $routeProvider config here... )
      /* Add $firebaseAuth to your controller */
      .controller("userProfileController", [ "$scope", "$firebaseAuth", function ($scope) {
      
          /* Be sure to put '$' before onAuthStateChanged() also */
          $firebaseAuth().$onAuthStateChanged(function (user) {
              if (user) {
                  /* {{email}} is now rendered without using $scope.$apply()! */
                  $scope.email = user.email; 
              } else {
                  // Do something else here.
              }
          });
      }]);
      

      结论:

      也就是说@georgeawg的解释仍然有效:如果在Angular Execution Context之外,你需要使用$scope.$apply()unless 服务已在 Angular 执行上下文中注入

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2015-02-01
        • 2022-08-17
        • 2017-04-03
        • 2021-07-16
        • 2018-12-18
        • 1970-01-01
        • 1970-01-01
        • 2017-03-28
        • 1970-01-01
        相关资源
        最近更新 更多