2012-08-01 42 views
19

如果我沒有正確表達這個意思,我很抱歉。我在ng-repeat中有一個ng-model的文本框,當我嘗試獲取文本框值時,它總是undefined。我只是想讓它顯示我在相應的文本框中輸入的內容。

這似乎是$scope的一個問題,所以我如何使$scope.postText全局或在控制器的根級別,以便它可以訪問?

這裏的的jsfiddle幫助明確的事情了:http://jsfiddle.net/stevenng/9mx9B/14/

回答

25

在你點擊表情,你可以參考你的savePost功能postText和訪問它。如果這不是ng-repeat,則可以成功訪問單個$scope.postText,但ng-repeat會爲每個項目創建一個新範圍。

Here是一個更新的小提琴。

<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); 
} 
+0

你將如何得到這個小提琴上班? http://jsfiddle.net/stevenng/VnQqH/5/ – Steve 2012-08-01 14:45:12

+9

http://jsfiddle.net/VnQqH/6/使用'this'來表示真實的當前範圍 – 2012-08-01 14:58:17

+0

感謝Renan幫助了很多。我通過傳遞像這樣的'save post'這樣的對象來實現它。但使用簡單的「這個」會好得多! – Steve 2012-08-01 15:31:25

45

由於@Gloopy已經指出,NG-重複創建您的posts陣列的每個項目一個新的子範圍。由於posts數組中的每個項目都是原語(字符串),因此ng-repeat還會在每個子作用域上創建一個post屬性,併爲它們中的每個指定數組中的適當值。在ng-repeat塊內部是ng-model="postText"。這將在每個子範圍上創建一個postText屬性。這裏是什麼,一切看起來像(爲4個作用域2):

ng-repeat scopes

當用戶鍵入一些文本輸入文本框之一,適當的灰色框將存儲的文本。 (例如,第二個(從頂部開始)灰色框將存儲用戶鍵入到「tech」文本框中的文本)。父範圍無法在子範圍中看到postText屬性 - 這是您遇到的問題。常見的有三種解決方案:

  1. @ Gloopy的回答是:定義父範圍功能(該子作用域可以訪問,因爲NG重複子作用域prototypically從父範圍繼承),並通過孩子scope屬性值(即,postText的值)直到父級。
  2. 在您的posts陣列中使用對象而不是基元。例如,
    在NG-repeat循環 $scope.posts = [ {type: 'tech'}, {type: 'news'}, ...];
    然後,使用
    <input type="text" ng-model="post.postText">
    因爲每個數組項是一個對象(而不是原始的),每個子範圍得到在陣列posts到相應的對象的引用,而不是副本(值)。因此,post.postText在父級$範圍屬性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。)

For more關於原型範圍繼承如何在Angular中工作的信息(以及更多圖片),請參閱What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

+0

我看不到2你可以調用savePost()而不傳遞任何東西。如何在不傳遞子對象或索引的情況下引用特定的子範圍? – 2014-05-09 18:48:57

+0

@Dean,好點。你可以通過'posts'循環來確定哪個更改(例如,如果你只需要一個「保存」按鈕)。或者,如果您希望每個帖子都有一個「保存帖子」鏈接,您可以傳遞'post.type'作爲參數。 – 2014-05-09 22:46:30

+0

如果您繪製了有關ParentScope無法看到輸入框中的文本的部分,該圖可能會更好。繪製紅線或其他方式,以顯示在框中輸入的內容對父級不可見。 – 2014-06-10 15:42:53

2

這可能是一個遲到的答案。請參考這個小提琴。 http://jsfiddle.net/X5gd2/ 請在文本框中輸入一些文字後點擊鏈接,參考螢火蟲控制檯。這個想法是爲每個在ng-repeat中重複的視圖都有一個itemcontroller。

該項目控制器:

function postItemController($scope){ 
    $scope.savePost = function(){ 
     console.log($scope.postText + " which belongs to " + $scope.post +" will be saved") 
    } 
} 
1

拆分模型成標題和值低於

angular.module('MyApp',[]); 

function PostCtrl($scope) { 
    $scope.posts = [{heading:'tech',value:''}, {heading:'news',value:''},  {heading:'sports',value:''},{heading:'health',value:''}]; 

    $scope.savePost = function(post){ 
     alert('post stuff in textbox: ' + post); 
    } 
} 

HTML ..

<div ng-app="MyApp"> 
    <div ng-controller="PostCtrl"> 
     <div ng-repeat="post in posts"> 
      <strong>{{post.heading}}</strong> 
      <input type="text" ng-model="post.value"> 
      <a href="#" ng-click="savePost(post.value)">save post</a> 
     </div> 
    </div> 
</div> 

Check out this Fiddle..