在 $('#x').change 或 angularfire $add 上使用 'Ng-If' "breaks" 程序

Using 'Ng-If' "breaks" program on a $('#x').change or an angularfire $add

我注意到我的代码中有两个实例使用 ng-if 导致我的程序开始工作。一方面,我为图片上传工具栏做了一个 ng-if="isOwnProfile"。

使用 ng-if 会导致事件侦听器停止工作。代码示例:

   $scope.myOwnProfile = false;
   if (userLoggedIn === userUID) {
     console.log('my images');
     $scope.myOwnProfile = true;
   } else {
     console.log('not my images');
   }
    $("#image-upload").change(function(e) {
    $scope.myOwnProfile = true;
    var file = e.target.files[0];
    var imageRef = firebase.storage().ref...

并在 HTML 中:

<section ng-if="myOwnProfile">
   <input id="image-upload" type="file" accept="image/*"> <br /><br />
</section>

在这种情况下,事件侦听器将停止工作并且不响应。 另一种情况是您向页面(和 firebase)添加消息。 代码:

    $scope.addMessage = function(){
    var date = new Date();
    $scope.messages.$add({
        timestamp: (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear(),
        from: $scope.visitorRealName.name,
        content: $scope.message
    });
    $scope.message = '';
};

HTML:

    <section ng-if="AreWeFriends === true || myOwnProfile === true">

    <form ng-submit="addMessage()">
        <input ng-model="message"> 
        <button type="submit">Add Message</button>
    </form>

    </section>

在第二种情况下,我收到来自 Firebase 的错误 "Key content was undefined. Cannot pass undefined in JSON. Use null instead"。

我无法确定为什么使用 ng-if 会导致这种情况发生?我所做的是将用户的个人资料设置为 true,无论他们是 a) 朋友还是 b) 这是该人自己的个人资料(这就是我更改 $scope 的原因)。

那是因为 ngIf 指令创建了它自己的子作用域。

ngIf 指令创建它自己的作用域,因此包含消息的 ngModel 指令设置在 ngIf 创建的作用域上指令,而不是你的控制器。

当您访问控制器中的值时,它不存在,所以它是 undefined。您实际上是将 undefined 传递给要添加到消息中的对象内的内容密钥,因此 Firebase 会抱怨。

要修复它,我建议使用控制器作为语法,以便您可以引用控制器,或者使用 ngShow 指令,它不会创建自己的子作用域。

这里有几个例子:

(function() {

  'use strict';

  angular.module('app', []);

})();

(function() {

  'use strict';

  angular.module('app').controller('MainController', MainController);

  MainController.$inject = ['$scope'];

  function MainController($scope) {

    var vm = this;

    $scope.test1 = test1;
    $scope.test2 = test2;
    $scope.test3 = test3;
    $scope.test4 = test4;

    function test1() {

      // this is undefined because there is no property `message` 
      // on the $scope of this controller
      alert($scope.message);

    }

    function test2() {

      // this contains the value binded to the message property 
      // of this controller because we used the controller as syntax
      alert(vm.message);

    }
    
    function test3(message) {

      // because we are passing in the message value we can
      // access it without caring where it came from
      alert(message);

    }
    
    function test4() {

      // the property `message` exists on this $scope because we
      // used the ngShow directive instead of the ngIf
      alert($scope.message4);

    }

  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<div ng-app="app" ng-controller="MainController as MainCtrl">

  <h4>Without controller as syntax</h4>
  <p>Does not work because message is not set on the controller's $scope, it's set on the scope created by the ngIf directive</p>
  <form ng-if="true">
    <input ng-model="message">
    <button ng-click="test1()">Submit</button>
  </form>
  
  <hr>

  <h4>With controller as syntax</h4>
  <p>Works because message is set on the controller so we can access it using `this` in our MainController</p>
  <form ng-if="true">
    <input ng-model="MainCtrl.message">
    <button ng-click="test2()">Submit</button>
  </form>

  <hr>
  
  <h4>Without controller as syntax but passing the message value into our function</h4>
  <p>Works because although message is set on the scope created by the ngIf directive, we are passing it to test3 in our MainController.</p>
  <form ng-if="true">
    <input ng-model="message">
    <button ng-click="test3(message)">Submit</button>
  </form>
  
  <hr>
  
  <h4>With ngShow directive instead of ngIf</h4>
  <p>Works because message is set on $scope from our contoller</p>
  <form ng-show="true">
    <input ng-model="message4">
    <button ng-click="test4()">Submit</button>
  </form>

</div>