ng-repeat中的AngularJS ng-model $范围未定义

pht*_*ven 19 angularjs

如果我没有正确措辞,我会提前道歉.我有一个ng-model内部文本框,ng-repeat当我尝试获取文本框值时,它始终是undefined.我只是希望它显示我在相应文本框中输入的内容.

它似乎是一个问题$scope,所以我如何使$scope.postText全局或控制器根级别,以便它可以访问?

这是帮助清理的JSFiddle:http://jsfiddle.net/stevenng/9mx9B/14/

Mar*_*cok 45

正如@Gloopy已经说过的那样,ng-repeat为posts数组中的每个项创建一个新的子范围.由于posts数组的每个项都是基元(字符串),因此ng-repeat还会post在每个子作用域上创建一个属性,并为每个子作用域分配适当的值.在ng-repeat块里面是ng-model="postText".这会在每个子作用域上创建一个postText属性.以下是所有内容(4个子范围中的2个):

ng-repeat范围

当用户在其中一个输入文本框中键入一些文本时,相应的灰色框将存储文本.(例如,第二个(从顶部)灰色框将用户键入的文本存储到"tech"文本框中.)父作用域无法在子作用域中看到postText属性 - 这就是您遇到的问题.有三种常见的解决方案:

  1. @ Gloopy的答案:在父作用域上定义一个函数(子作用域可以访问它,因为ng-repeat子作用域原型继承自父作用域)并将子作用域属性值(即postText的值)传递给父作用域.
  2. posts数组中使用对象而不是基元.例如,
    $scope.posts = [ {type: 'tech'}, {type: 'news'}, ...];
    然后在你的ng-repeat循环中,使用
    <input type="text" ng-model="post.postText">
    因为每个数组项都是一个对象(而不是一个基元),每个子作用域都会获得对数组中相应对象的引用posts,而不是(值的)副本.因此,post.postText在父$ scope属性上创建posts,因此它对父作用域可见.(因此,在这种情况下,子范围将简单地调用savePost()- 不需要将任何值传递到父范围.)
    换句话说,如果用户在第一个文本框中键入"this is tech related",posts父节点中的数组将自动更新如下:
    $scope.posts = [ {type: 'tech', postText: 'this is tech related'}, {type: 'news'}, ...];
    最后一个注释:在用户键入内容之前,postText属性不会添加到posts对象.
  3. 使用ng-model="$parent.someProperty"的表单元素绑定到一个属性对父范围,而不是对孩子的范围.这个解决方案很难为你的场景实现,而且它是一个相当脆弱的解决方案,因为它依赖于范围继承的HTML结构......但我提到它是为了完整性.

(@Renan在评论@ Gloopy的答案时提出了第四个解决方案.这是一个类似的解决方案1.但是有一个变化:this使用而不是将值传递给父级.我不是这种方法的粉丝因为它很难确定访问或修改哪个$ scope.我认为在$ scope上定义的函数最好只访问和修改它们自己的$ scope.)

有关原型范围继承如何在Angular中工作的更多信息(以及更多图片),请参阅AngularJS中范围原型/原型继承的细微差别是什么?


Glo*_*opy 25

在您的单击表达式中,您可以引用postText并在savePost函数中访问它.如果这不是ng-repeat,您可以$scope.postText成功访问单个,但ng-repeat为每个项目创建一个新范围.

是一个更新的小提琴.

<div ng-repeat="post in posts">
   <strong>{{post}}</strong>
   <input type="text" ng-model="postText">
   <a href="#" ng-click="savePost(postText)">save post</a>
</div>

$scope.savePost = function(post){
   alert('post stuff in textbox: ' + post);
}
Run Code Online (Sandbox Code Playgroud)

  • http://jsfiddle.net/VnQqH/6/使用`this`来指代实际的当前范围 (9认同)