1

我正在使用 OnesnUI 和 AngularJS 编写一个应用程序,使用 ng-model 从 DOM 元素获取输入。

这是我的代码

<body>
  <ons-screen>
      <ons-page class="center" ng-controller="page1Ctrl">
    <ons-navigator title="Page 1">
        <div class="center">
          <h1>Pharmy</h1>
            <ons-text-input ng-model="medName" placeholder="Enter Medicine Name" style="display:block; width:100%;" id="test"></ons-text-input>
            <div style="position:relative">
                <ons-text-input ng-model="location" placeholder="Enter Location" style="display:block; width:100%; margin-top:10px;"></ons-text-input>
                <ons-icon icon="search" style="position:absolute;right:10px;top:5px;"></ons-icon>
            </div>
            <ons-button ng-click="goToPage2()"
                        style="width:10%; margin-top:10px;">
                <ons-icon icon="search"></ons-icon>
            </ons-button>
        </div>
    </ons-navigator>
          </ons-page>
  </ons-screen>
</body>

并尝试从输入文本框中检索值,这是我的app.js

    (function () {
        'use strict';
        var app = angular.module('myApp', ['onsen.directives']);
        app.controller('page1Ctrl',['$scope','pageService',function($scope,pageService){
            $scope.$watch('medName',function(newVlaue){
                console.log('Watching YOU !' + newVlaue);
            });
            console.log($scope.medName);
            $scope.goToPage2 = function(){
                console.log('Going to page2 !');
                console.log($scope.medName);
                pageService.start($scope.medName);
                $scope.ons.navigator.pushPage("page2.html");
            }
        }]);
    })();

为什么是medName打印值undefined

4

4 回答 4

4

如果我必须在 Angular 中命名一个适当的痛苦,那就是范围继承。

如果您假设$scope.foo = "hello"是控制器,然后您创建该控制器的子范围,然后尝试为其分配一个新值,foo该值将在该新范围内创建一个 foo值。您的父控制器永远不会看到更改。

在您的问题中,您没有创建新范围,但 OnsenUI 可能在ons-screenor上这样做ons-navigator。然后您的输入在一个新的子范围内,如果您尝试分配newMed它,它将在子范围内这样做。

规则始终是拥有对象,即所谓的dot rule(检查here)。

所以如果你不想再遇到这个问题,总是像我在评论中告诉你的那样,创建类似的东西$scope.meds = {},然后ng-model="meds.newMed"因为这样,它会先搜索meds父母,如果找到,它会使用它这就是你想要做的。

这是第一个做错的例子:http ://plnkr.co/edit/IJZOa1pXtcQePiEVMzjZ?p=preview

<body ng-controller="MainCtrl">
  <foo>
    <input ng-model="name"> <br />
    Inside new scope: {{ name }}
  </foo>
  <br />
  On the parent scope: {{ name }}

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

app.directive('foo', function() {
  return {
    restrict: 'E',
    scope: true
  };
});

在这里,我们是一个指令,它正在创建一个名为 foo 的新范围。然后在我们的 html 里面,<foo>我们放了一个ng-modelwith name。它读取当前范围,哦,不在那里,所以它上升到控制器的范围并找到它。所以你World在输入上看到了。当您更改输入时,它将获取它的内容并分配一个新值。如何?它进入它的范围,并分配它。问题是它的范围是由创建的新范围foo,因此,父级将永远不会看到任何更改。

让我们看看第二个例子:http ://plnkr.co/edit/BSx37PpAEbPnHfs2jr5o?p=preview

<body ng-controller="MainCtrl">
  <foo>
    <input ng-model="user.name"> <br />
    Inside new scope: {{ user.name }}
  </foo>
  <br />
  On the parent scope: {{ user.name }}
</body>

-

app.controller('MainCtrl', function($scope) {
  $scope.user = {
    name: 'World'
  };
});

app.directive('foo', function() {
  return {
    restrict: 'E',
    scope: true
  };
});

在这里,同样的例子,但有细微的变化。在这里,我们有name一个名为 的对象user。当输入读取它时,没有区别,但是当它要分配一个新值时,它会做一些不同的事情,例如:嘿,新范围,你有这个用户对象吗?Errr no...好的,父母,你有这个用户对象吗?我愿意。好,然后在其中放入一个name使用此内容调用的属性。

你看得到差别吗?在它没有问它的父级之前,它只是在name内部范围上创建了,但是如果你使用对象,它会首先尝试找到对象,这正是我们需要的。

TL ; DR; 是:总是使用对象,因为发生在你身上的事情是你使用的一些指令正在创建新的作用域,而你的新分配将在内部作用域上创建。

于 2014-07-23T12:44:29.293 回答
0

您的代码实际上有效,您是否在实际输入中输入了一些内容?它在开头写 undefined 因为它是,它没有在范围内定义,并且您的输入值为 null。

我很快做了一个jsfiddle,这是(基本上是你的)代码。HTML:

<div ng-app="myApp">
    <div ng-controller="page1Ctrl">
        <input ng-model="medName" />
        <p ng-if="medName">{{medName}}</p>
    </div>
</div>

JS:

var app = angular.module('myApp', []);
app.controller('page1Ctrl',['$scope', function($scope){
    $scope.$watch('medName',function(newVlaue){
        console.log('Watching YOU !' + newVlaue);
    });
    console.log($scope.medName);
}]);

这是 jsfiddle: http: //jsfiddle.net/q3z22/4/ 你会在控制台中看到开头的“未定义”,然后是你在输入中写的任何内容。如果您不希望这样,只需通过编写在范围内定义,$scope.medName = '';您将在开始时有一个空字符串。

于 2014-07-23T12:39:41.383 回答
0

创建了一个简单的jsfiddle来展示它是如何在 Angular 中完成和运行良好的。

你的第一个 console.log 将是未定义的,因为你没有在控制器中设置任何东西

就像是

 $scope.medName = '';

会有所帮助的。

我在示例中用于演示的控制器的代码片段:

function test($scope){
    $scope.medName = '';
    console.log($scope.medName);
    $scope.$watch('medName',function(newValue){
        console.log("new Value:"+newValue);
    });
    $scope.getUpdatedScope = function(){
        console.log($scope.medName);
    }
}
于 2014-07-23T12:35:16.377 回答
0

您是否在某处设置了 ng-app 指令?尝试将其添加到 body 标签中,如下所示:

<body ng-app="myApp">
于 2014-07-23T12:40:45.950 回答