2

我正在尝试了解 AngularJS 的数据绑定功能,并且有一个新手问题:

在下面的示例中,当我在文本框中键入名称时,问候语不会更新。

<html ng-app>
<head>
    <script src="js/angular.js"></script>
    <script>
        function myCtl($scope){
            $scope.person=$scope.fname;
        }
    </script>
</head>
<body>
        <div ng-controller="myCtl">
            <input ng-model="fname"/>
            <br/>               
            Hello, {{person}}
        </div>
</body>

当我改变

Hello, {{person}}

Hello, {{fname}}

当我键入时,问候语会更新。我对为什么第二种语法有效但第一种无效的原因感到困惑。

4

3 回答 3

4

$scope.person=$scope.fname在 $scope 对象上创建一个person原始属性并为其赋值undefined(因为在执行这行代码时 $scope.fname 还不存在)。这是您在输入文本框之前的 $scope 的样子:

输入前的 $scope

在您在文本框中输入内容后,Angular 会自动fname在 $scope 上创建一个原始属性,并且自动双向数据绑定会不断地将值设置为文本框中的任何内容。所以,如果我输入“Mark”,那么 $scope 现在看起来像这样:

键入后的 $scope

现在应该清楚为什么{{person}}什么都不显示,而是{{fname}}显示文本框中的内容。

于 2013-01-07T22:38:22.937 回答
2

因为,当您在输入字段中输入时,$scope.fname正在更改,而不是$scope.person.

您可以使用$watchon修复它fname

$scope.$watch('fname', function(value) {
   if(value) {
      $scope.person = value;
   }
}, true);
于 2013-01-07T07:19:21.460 回答
2

对于 asgoth 的回答,我还要补充一点,这段代码掩盖了一个误解:

$scope.person=$scope.fname;

此代码不会在每次视图中发生某些事情时运行,而只会在执行控制器时运行一次。您似乎正在尝试设置$scope.person$scope.fname. 但是$scope.fname没有定义——这是你的控制器需要做的。因此,您的视图和控制器都引用了未定义的值。

在像这样的简单情况下,您的控制器应该在启动时初始化您的模型:

function myCtl($scope){
    scope.person = {
        fname: '',
        lname: '',
        email: ''
    };
}

然后将元素绑定到人的属性(例如ng-model="person.fname")。

现在,无论何时代码在您的控制器中运行,它都会自动person.fname为您提供正确的角度 - 您永远不需要“从您的视图中读取”。

function myCtl($scope){
    $scope.person = {
        fname: '',
        lname: '',
        email: ''
    };
    function validate() {
        if (!$scope.email.match(/@/) return window.alert('Please enter a valid email address!');
    }
}

从你的角度来看,你会这样做:

<form ng-submit="validate()">

或者

<button ng-click="validate()">
于 2013-01-07T11:59:19.050 回答