AngularJS ng-model 不工作?

Posted

技术标签:

【中文标题】AngularJS ng-model 不工作?【英文标题】:AngularJS ng-model not working? 【发布时间】:2015-12-12 13:15:21 【问题描述】:

我有这个 index.html,其中有一个导航栏,在我的单页应用程序的所有页面上都可以看到。导航栏容器 div 使用 ng-controller="LoginCtrl" 值,因此我还将从我的 Angular 应用程序 (app.js) 中包含该控制器

由于某种原因,当通过ng-click 指令调用doLogin() 时,通过ng-model 绑定的变量usernamepassword 显示为未定义?那是在我在绑定到我的控制器变量的文本框中键入值之后。

index.html

<!DOCTYPE html>

<html ng-app="myApp">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
    <base href="/">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>

</head>
<body>

    <div ng-controller="LoginCtrl">
        <nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#">TriviaAttack!</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
                        <div class="form-group">
                            <input type="text" placeholder="Email" class="form-control" ng-model="username">
                        </div>
                        <div class="form-group">
                            <input type="text" placeholder="Password" class="form-control" ng-model="password">
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
                        </div>                  
                    </form>
                </div>
            </div>
        </nav>
        <div ng-view></div>
    </div>

    <script src="./app/app.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">

</body>
</html>

app.js

...
myApp.controller('LoginCtrl', function($rootScope, $location, AuthService, AuthToken) 

    $rootScope.doLogin = function() 
        console.log($rootScope.username);
        console.log($rootScope.password);
    

);
...

【问题讨论】:

使用$scope 而不是$rootScope。对于应用程序,我们应该让我们的$rootScope 尽可能的薄。 嗨,$scope 也不起作用,都说未定义。 分享更多代码或创建小提琴。我看不到你的模块声明 这是我的模块声明 var myApp = angular.module('myApp',['ngRoute', 'ngStorage']); 这能回答你的问题吗? Ng-model does not update controller value 【参考方案1】:

当您在文本字段中键入时,将在 ng-controller 的范围内创建一个 inputModel 原始属性。输入模型是在当前范围内生成的,而不是rootScope

var app = angular.module('myApp', []);
app.controller('LoginCtrl', function($scope, $http) 
  $scope.doLogin = function() 
        console.log($scope.username);
        console.log($scope.password);
    
);

查看Plunker

【讨论】:

将 $scope 注入 LoginCtrl 是我最初尝试做的,但它不起作用所以我只是尝试了 $rootScope 我已将我的代码更新为使用您所展示的 $scope,但它无法正常工作。 不,只是共享 $scope.username 和 $scope.password 在 console.log 输出中未定义。即使它们通过 index.html 中的文本框上的 ng-model="username" 绑定到 $scope 变量 @DavidStampher 请立即查看 检查我在下面发布的答案,我向 doLogin(user, pass) 添加了参数,并在我的 ng-click 按钮中调用了 doLogin,如下所示 doLogin(user.name, user.pass) 并且它有效.【参考方案2】:

使用模型而不是使用原始类型。

您应该使用$rootScope.user.nameng-model 将是user.name)而不是使用$rootScope.username$rootScope.user.passwordng-model 将是user.password)而不是$rootScope.password

这个问题实际上发生在 javascript 的原型模型上。如果你想知道它在 angularjs 中的适用性,你可以通过这个article。这肯定会有所帮助:)

编辑:当您在使该代码工作时遇到问题时,我已经制作了您的代码的工作副本。请看一下:

<!DOCTYPE html>

<html ng-app="myApp">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
    <base href="/">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>

</head>
<body>

    <div ng-controller="LoginCtrl">
        <nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#">TriviaAttack!</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
                        <div class="form-group">
                            <input type="text" placeholder="Email" class="form-control" ng-model="user.name">
                        </div>
                        <div class="form-group">
                            <input type="text" placeholder="Password" class="form-control" ng-model="user.password">
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
                        </div>
                    </form>
                </div>
            </div>
        </nav>
        <div ng-view></div>
    </div>

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

</body>
</html>

<script>
    var myApp = angular.module("myApp", []);
    myApp.controller('LoginCtrl', function ($scope, $location) 

        $scope.user =  name: "", password: "" ;
        $scope.doLogin = function () 
            console.log($scope.user.name);
            console.log($scope.user.password);
        

    );
</script>

【讨论】:

嗨,我将 index.html 中的 ng-model 更改为 ng-model="user.name" 并将我的 LoginCtrl 的 doLogin 函数更改为:console.log($rootScope.user.name);它说无法读取未定义的属性“名称”? 你需要先初始化对象。可能带有一个空对象。比如 $rootScope.user =name:"",password:""; 我刚刚这样做了,它使我提到的异常消失了,但是当我在输入框中输入文本时,变量没有被更新,根据在 doLogin 中调用的 console.log 所以它显示 $rootScope.user.name 是一个空字符串,因为它也被初始化了,即使它应该由 ng-model 更新 为了您的方便,我已经编辑了我的答案。请看一下【参考方案3】:

使用$scope 而不是$rootScope 在控制器中获取ng-model

【讨论】:

我已将 $scope 注入 LoginCtrl,创建了一个名为 user 的空 JSON 对象,其中包含属性名称和 pass,将其附加到 $scope,并将我的 ng-models 更新为 user.name 和 user.pass,并且 console.log 将 user.name 和 user.pass 显示为空字符串,即使它们应该由于 ng-model 而更新了它们的值? app.controller('LoginCtrl', function($scope, $http) $scope.doLogin = function() console.log($scope.username); console.log($scope .password); );【参考方案4】:

经过一番挫折,我找到了自己问题的答案。将用户名和密码参数添加到我的 doLogin() 函数,然后使用指令 ng-click="doLogin(user.name, user.pass)" 按我的意愿工作。不知道为什么它没有像我尝试的那样工作,但是哦,好吧。

【讨论】:

非常令人沮丧... 我花了 2 个小时试图弄清楚为什么在我为我的开发新模块时会发生完全相同的问题主应用程序。刚刚尝试按照您的建议进行操作,并且可以正常工作。在我的应用程序中,我还有其他功能可以操纵模型而无需将它们指定为参数并且可以完美地工作。 您能否将您的答案标记为已接受或主要答案?我认为它可以在我们的确切情况下帮助其他人 @DincăAlexandru 嘿,我标记了它,但我能够以某种方式让它工作,而无需将我的变量作为参数提供给 doLogin()。但是,无论出于何种原因,这也确实解决了我原来的问题。 嘿@David,我猜你无法解释不知何故?我仍然很好奇为什么我把这些时间浪费在像这样微不足道的事情上。 请参阅***.com/a/22768720/1885735 字符串是一个原语。当 Angular 分配值时,它会更改指向该值的指针。因此,当控制器查看旧值时,它具有指向该值的旧指针。

以上是关于AngularJS ng-model 不工作?的主要内容,如果未能解决你的问题,请参考以下文章

没有 ng-model AngularJS 选择不起作用

angularjs在ng-model中添加空格

Angularjs:在更新ng-model时选择不更新

使用 ng-model 时 AngularJS $scope 不更新(ng-change 触发?)

如何在angularjs中的选择框或内部选项中使用ng-model?

JQuery 与 angularjs ng-model 的集成