如何在$ asyncValidators中实现Firebase?

时间:2015-08-26 10:01:01

标签: angularjs firebase angularfire angular-ngmodel

我想在我的Firebase应用中强制执行unique usernames,并立即让用户知道是否已经插入了用户名。 我查看了AngularJS的ngModel,因为它的控制器中有一个内置的asyncValidator(example in Custom Validation),但是我仍然坚持让它运行起来。

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id='optionList'>
  <option value='ALL'>ALL</option>
  <option value='M1'>M.1</option>
  <option value='M2'>M.2</option>
  <option value='M3'>M.3</option>
</select>
<table id='ErrorDisplayTable'>
  <tr id="ALL">
    <th>A</th>
    <th>B</th>
    <th>C</th>
    <th>D</th>
    <th>E</th>
  </tr>
  <tr>
    <tr id='M1'>
      <!--- using a dot in a id is very bad! -->
      <td>L11</td>
      <td>M.1</td>
      <td>( 11:31:52.250 ; 11:34:45.842 )</td>
      <td>( 2038 ; 4113 )</td>
      <td>TQ &#8712 [1-7] &#10154 173s.</td>
    </tr>
    <tr id='M2'>
      <!--- using a dot in a id is very bad! -->
      <td>L11</td>
      <td>M.2</td>
      <td>( 11:31:52.250 ; 11:34:45.842 )</td>
      <td>( 1056 ; 3587 )</td>
      <td>TQ &#8712 [1-7] &#10154 84s.</td>
    </tr>
    <tr id='M3'>
      <!--- using a dot in a id is very bad! -->
      <td>L11</td>
      <td>M.3</td>
      <td>( 11:31:52.250 ; 11:34:45.842 )</td>
      <td>( 10056 ; 10598 )</td>
      <td>TQ &#8712 [1-7] &#10154 25s.</td>
    </tr>
</table>

指令

<form name="settings" novalidate>
  <div>
    Username:
    <input type="text" ng-model="user.username" name="username" app-username><br>
    <span ng-show="settings.username.$pending.appUsername">Checking if this username is available...</span>
    <span ng-show="settings.username.$error.appUsername">This username is already taken!</span>
  </div>
</form>

是否可以在asyncValidator中使用Firebase? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

是的,这是可能的。但是,您遇到的问题与Firebase无关。根据您链接的Angular文档:

  

添加到对象的函数必须返回一个必须在有效时解析或在无效时被拒绝的承诺。

因此,您只需要在Angular文档中使用延迟,或使用$q(function(resolve, reject) {...})。我在下面使用了后者。

app.directive('appUsername', function($q) {
  return {
    require: 'ngModel',
    link: function (scope, elm, attrs, ctrl) {
      var ref = new Firebase("https://<MY-APP>.firebaseio.com");
      ctrl.$asyncValidators.appUsername = function (modelValue, viewValue) {
        return $q(function(resolve, reject) {
          if (ctrl.$isEmpty(modelValue)) {
            // consider empty model valid
            resolve();
          }
          var usernameRef = ref.child('users').orderByChild('username').equalTo(modelValue);
          usernameRef.once('value', function (snapshot) {
            if (snapshot.val() === null) {
              // username does not yet exist, go ahead and add new user
              resolve();
            } else {
              // username already exists, ask user for a different name
              reject();
            }
          });
        });
      };
    };
  };
});