Ionic / Angular JS - $scope 问题:无法读取未定义的 属性 'length'

Ionic / Angular JS - $scope issue : Cannot read property 'length' of undefined

我不能在 ionic 中使用 $scope,似乎 $scope 不起作用。

让我们看一个非常简单的例子: App.js :

angular.module('TestApp', ['ionic','TestCtrl'])
.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
})
.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('login', {
        url: "/login",
        templateUrl: "views/login.html",
        controller : "login"   
    });
  $urlRouterProvider.otherwise('/login');
});

Login.js :

angular.module('TestCtrl',[])
.controller('login', function($scope,$rootScope) {
    $scope.giveClass = function() {
      console.log($scope.email.length);
    }
});

Index.html :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
    <script src="lib/ionic/js/ionic.bundle.js"></script>
    <script src="cordova.js"></script>
    <script src="js/app.js"></script>
    <script src="controllers/login.js"></script>
  </head>
  <body ng-app="TestApp">
    <ion-nav-view></ion-nav-view>
  </body>
</html>

Login.html :

<ion-view>
    <ion-header-bar  class="bar-calm">
    <h1 class="title" ng-model="test">Login</h1>
  </ion-header-bar>
  <ion-content>
    <form ng-submit="postLogin()"  name="loginForm">
        <div class="list list-inset">
            <label class="item item-input" ng-class="giveClass()">
                <i class="icon  icon-fixed-width ion-at placeholder-icon"></i>
                <input type="email" name="email" ng-model="email" placeholder="Veuillez entrer votre adresse email" required/>
            </label>
            <label class="item item-input">
                 <i class="icon ion-key  icon-fixed-width   placeholder-icon"></i>
                 <input type="password"  name="password" ng-model="password" placeholder="Veuillez entrer votre mot de passe" required/>
            </label>    
          <div class="list">
           <label class="item">
                <button class="button button-block button-positive" type="submit">Se connecter</button>
           </label>
           <label class="item">
             <button class="button button-block button-royal" type="submit">S'enregistrer</button>
           </label>
         </div>
        </div>
        </form>
    </ion-content>
</ion-view>

当我执行此应用程序控制台时(console.log(...) in login.js)return

"Cannot read property 'length' of undefined"

不确定,您打算在哪里设置模型 属性 email。我的意思是,'email',您传递给 Login.html:

中的 ng-model
<ion-view>
    ...
    // here is expected model 'email'
    <input type="email" name="email" ng-model="email" 
        placeholder="Veuillez entrer votre adresse email" required/>
   ...

以防万一 angular 找不到它 - 它会创建那个,但是在 $scope 上。范围将是第一个参数而不是第二个参数 Login.js:

.controller('login', function($scope,$rootScope) {
    $scope.giveClass = function() {
      // here we can expect 'email' to be created for us
      // but not on $rootScope
      // it will be available on $scope
      console.log($rootScope.email.length);

所以,这一切意味着:

  • 没有明确的 $rootScope.email
  • 也不属于 $scope.email
  • 因为我们使用了 ng-model="email",所以我们可以预期,angular 会为我们创建这样的 属性,但在 $scope 上,而不是在 $rootScope

所有这些都将以

结束

Cannot read property 'length' of undefined

如果我们使用$rootScope.email.length,甚至$scope.email.length。这两个都应该首先初始化或检查它们是否存在:

解决方案:方法是启动这样的 属性 test (不需要,但我们知道发生了什么)。更好的是,使用一些模型 (并有一个点 - 在这里检查更多:Model in a modal window in angularjs is empty

.controller('login', function($scope,$rootScope) {
     $scope.Model = {};
     // if possible - init it, 
     // $scope.Model.email= "init value";
     $scope.giveClass = function() {
        // if we need user to init that, 
        // we have to check if that value was set
        if($scope.Model.email){
            console.log($scope.email.length);
        }
     }

视图

ng-model="Model.email"

感谢 Radim,我需要在 ng-model 中使用一个点作为对象,并且 input-type="mail" 仅当电子邮件匹配 regexp

时才会绑定

所以工作示例是: Apps.js:

angular.module('TestApp', ['ionic','TestCtrl'])
.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
})
.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('login', {
        url: "/login",
        templateUrl: "views/login.html",
        controller : "login"   
    });
  $urlRouterProvider.otherwise('/login');
});

Login.js:

angular.module('TestCtrl',[])
.controller('login', function($scope,$rootScope) {
    $scope.Model = {};
    $scope.giveClass = function() {
       if($scope.Model.email){
            console.log($scope.email.length);
    }
});

Index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
    <script src="lib/ionic/js/ionic.bundle.js"></script>
    <script src="cordova.js"></script>
    <script src="js/app.js"></script>
    <script src="controllers/login.js"></script>
  </head>
  <body ng-app="TestApp">
    <ion-nav-view></ion-nav-view>
  </body>
</html>

Login.html:

<ion-view>
    <ion-header-bar  class="bar-calm">
    <h1 class="title">Login</h1>
  </ion-header-bar>
  <ion-content>
    <form ng-submit="postLogin()"  name="loginForm">
        <div class="list list-inset">
            <label class="item item-input" ng-class="giveClass()">
                <i class="icon  icon-fixed-width ion-at placeholder-icon"></i>
                <input type="text" name="email" ng-model="Model.email" placeholder="Veuillez entrer votre adresse email" required/>
            </label>
            <label class="item item-input">
                 <i class="icon ion-key  icon-fixed-width   placeholder-icon"></i>
                 <input type="password"  name="password" ng-model="password" placeholder="Veuillez entrer votre mot de passe" required/>
            </label>    
          <div class="list">
           <label class="item">
                <button class="button button-block button-positive" type="submit">Se connecter</button>
           </label>
           <label class="item">
             <button class="button button-block button-royal" type="submit">S'enregistrer</button>
           </label>
         </div>
        </div>
        </form>
    </ion-content>
</ion-view>